Libraries

# Load necessary libraries
library(forecast)
Registered S3 method overwritten by 'quantmod':
  method            from
  as.zoo.data.frame zoo 
library(tseries)

    ‘tseries’ version: 0.10-55

    ‘tseries’ is a package for time series analysis and computational finance.

    See ‘library(help="tseries")’ for details.
library(tidyverse)
── Attaching core tidyverse packages ───────────────────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.1     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.0
✔ ggplot2   3.4.2     ✔ tibble    3.2.1
✔ lubridate 1.9.2     ✔ tidyr     1.3.0
✔ purrr     1.0.1     ── Conflicts ─────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(readr)
library(ggplot2)
library(zoo)

Attaching package: ‘zoo’

The following objects are masked from ‘package:base’:

    as.Date, as.Date.numeric
library(TSA)
Registered S3 methods overwritten by 'TSA':
  method       from    
  fitted.Arima forecast
  plot.Arima   forecast

Attaching package: ‘TSA’

The following object is masked from ‘package:readr’:

    spec

The following objects are masked from ‘package:stats’:

    acf, arima

The following object is masked from ‘package:utils’:

    tar
library(rugarch)
Loading required package: parallel

Attaching package: ‘rugarch’

The following object is masked from ‘package:purrr’:

    reduce

The following object is masked from ‘package:stats’:

    sigma
library(forecast)
library(PerformanceAnalytics)
Loading required package: xts

######################### Warning from 'xts' package ##########################
#                                                                             #
# The dplyr lag() function breaks how base R's lag() function is supposed to  #
# work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or       #
# source() into this session won't work correctly.                            #
#                                                                             #
# Use stats::lag() to make sure you're not using dplyr::lag(), or you can add #
# conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop           #
# dplyr from breaking base R's lag() function.                                #
#                                                                             #
# Code in packages is not affected. It's protected by R's namespace mechanism #
# Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning.  #
#                                                                             #
###############################################################################

Attaching package: ‘xts’

The following objects are masked from ‘package:dplyr’:

    first, last


Attaching package: ‘PerformanceAnalytics’

The following objects are masked from ‘package:TSA’:

    kurtosis, skewness

The following object is masked from ‘package:graphics’:

    legend
library(xts)
library(quantmod)
Loading required package: TTR

FRED Monthly Retail Sales

Load & Inspect the Data

file_path <- "~/Documents/GitHub/MA-641-Course-Project/Scratch Work/RSXFSN.csv"

retail_sales_data <- read_csv(file_path)
Rows: 126 Columns: 2── Column specification ─────────────────────────────────────────────────────────────────────
Delimiter: ","
dbl  (1): RSXFSN
date (1): DATE
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# Convert the DATE column to Date type
retail_sales_data$DATE <- as.Date(retail_sales_data$DATE, format="%Y-%m-%d")

The following dataset is part of the Advance Monthly Retail Trade Survery conducted by the U.S Census Bureau, retrieved from FRED and measures the retail trade activity in the United States. It provides an early estimate of monthly sales for retail and food service companies capturing consumer demand for goods and services.

The RSXFSN data series measures the dollar value of sales and is reported on millions of dollars. This data is not seasonally adjusted and is released monthly. The period of observation for this project spans a 10 year period from January 2014 to May 2024, totaling 126 observations.

head(retail_sales_data)
summary(retail_sales_data)
      DATE                RSXFSN      
 Min.   :2014-01-01   Min.   :337453  
 1st Qu.:2016-08-08   1st Qu.:405145  
 Median :2019-03-16   Median :449590  
 Mean   :2019-03-17   Mean   :474666  
 3rd Qu.:2021-10-24   3rd Qu.:554140  
 Max.   :2024-06-01   Max.   :668957  
# Check the number of rows in the original dataset
num_data_points <- nrow(retail_sales_data)
cat("Number of data points in the original dataset:", num_data_points, "\n")
Number of data points in the original dataset: 126 

Descriptive Analysis

Time Series Plot

# Plot the original data
ggplot(data = retail_sales_data, aes(x = DATE, y = RSXFSN)) +
  geom_line(color = "blue") +
  labs(title = "Time Series of Monthly Retail Sales",
       x = "Date",
       y = "Retail Sales") +
  theme_minimal()

The time series displays a noticeable upward trend in retails sales with periodic spikes in the final months of the year, indicating the presence of seasonality.

Box Plot

# Create a time series object
ts_data <- ts(retail_sales_data$RSXFSN, start = c(2014, 12), frequency = 12)

boxplot(ts_data ~ cycle(ts_data), main="Seasonal Boxplot of Monthly Retail Sales", ylab = "Sales", xlab = "Month")

Although it makes sense that the month of November would see peak sales due to Black Friday and Cyber Monday events, it seems counter-intuitive that December would have such a stark decrease in sales, considering the holiday season.

ACF and PACF of Original Data

# Create ACF plot
acf(retail_sales_data$RSXFSN, main = "ACF of Monthly Retail Sales", lag.max = 100)

# Create PACF plot
par(mar=c(5, 5, 4, 2) + 0.1)

pacf(retail_sales_data$RSXFSN, main = "PACF of Monthly Retail Sales", lag.max = 100)

ADF Test

adf_test_result <- adf.test(retail_sales_data$RSXFSN)
print(adf_test_result)

    Augmented Dickey-Fuller Test

data:  retail_sales_data$RSXFSN
Dickey-Fuller = -2.4875, Lag order = 4, p-value = 0.3739
alternative hypothesis: stationary

The data shows clear non-stationarity. Therefore, we proceed with differencing measures to achieve stationarity.

Obtaining Stationary Time Series

One order of differencing

# Calculate the differences of the RSXFSN series
diff_series <- diff(retail_sales_data$RSXFSN)

# Plot the differenced data
diff_data <- data.frame(DATE = retail_sales_data$DATE[-1], Difference = diff_series)

ggplot(data = diff_data, aes(x = DATE, y = Difference)) +
  geom_line(color = "red") +
  labs(title = "Differenced Time Series of Monthly Retail Sales",
       x = "Date",
       y = "Difference in Retail Sales") +
  theme_minimal()

adf_test_result <- adf.test(diff_series)
Warning: p-value smaller than printed p-value
print(adf_test_result)

    Augmented Dickey-Fuller Test

data:  diff_series
Dickey-Fuller = -8.0818, Lag order = 4, p-value = 0.01
alternative hypothesis: stationary

p-value from ADF = 0.01 < 0.05 -> stationary

Log transformation and one order of differencing

# Take log transformation of data
log_series <- log(retail_sales_data$RSXFSN)

# Apply differencing
diff_log_series <- diff(log_series)

# Plot the differenced data
diff_log_data <- data.frame(DATE = retail_sales_data$DATE[-1], Difference = diff_log_series)

ggplot(data = diff_data, aes(x = DATE, y = Difference)) +
  geom_line(color = "red") +
  labs(title = "Differenced Time Series of Monthly Retail Sales",
       x = "Date",
       y = "Difference in Retail Sales") +
  theme_minimal()

adf_test_result <- adf.test(diff_log_series)
Warning: p-value smaller than printed p-value
print(adf_test_result)

    Augmented Dickey-Fuller Test

data:  diff_log_series
Dickey-Fuller = -7.9621, Lag order = 4, p-value = 0.01
alternative hypothesis: stationary

One order of differencing, both with and without taking the logarithmic transformation, achieves stationarity.

One order seasonal differencing

# Apply seasonal differencing to the RSXFSN series
seasonal_diff_series <- diff(retail_sales_data$RSXFSN, lag = 12)

# Create a data frame for the seasonally differenced data
seasonal_diff_data <- data.frame(DATE = retail_sales_data$DATE[-(1:12)], Difference = seasonal_diff_series)

# Plot the seasonally differenced data
ggplot(data = seasonal_diff_data, aes(x = DATE, y = Difference)) +
  geom_line(color = "green") +
  labs(title = "Seasonally Differenced Time Series of Monthly Retail Sales",
       x = "Date",
       y = "Seasonal Difference in Retail Sales") +
  theme_minimal()

Seasonal differencing plut additional first differencing on seasonally differenced data

# Apply seasonal differencing to the RSXFSN series
seasonal_diff_series <- diff(retail_sales_data$RSXFSN, lag = 12)

# Perform additional first differencing on seasonally differenced data to ensure stationarity
combined_diff_data <- diff(seasonal_diff_series)

# Create a data frame for the seasonally differenced data
doubly_diff_data <- data.frame(DATE = retail_sales_data$DATE[-(1:13)], Difference = combined_diff_data)

# Plot the seasonally differenced data
ggplot(data = doubly_diff_data, aes(x = DATE, y = Difference)) +
  geom_line(color = "purple") +
  labs(title = "Combined Seasonally Differenced Time Series of Monthly Retail Sales",
       x = "Date",
       y = "Seasonal Difference in Retail Sales") +
  theme_minimal()

adf_test_result <- adf.test(combined_diff_data)
Warning: p-value smaller than printed p-value
print(adf_test_result)

    Augmented Dickey-Fuller Test

data:  combined_diff_data
Dickey-Fuller = -7.1014, Lag order = 4, p-value = 0.01
alternative hypothesis: stationary

Taking a seasonal difference of the data, and then an additional order of differencing produces the time series most resembling white noise, albeit with clear volatility between 2020 and 2022. This can perhaps be explained by the COVID-19 pandemic, which saw many store closures and and ceasing of retail activities. We now investigate the ACF and PACF plots with this data.

ACF and PACF

# Plot ACF for the differenced data
acf(combined_diff_data, main="ACF of Differenced RSXFSN", lag.max=50)

# PACF plot for differenced data
par(mar=c(5, 5, 4, 2) + 0.1)

pacf(combined_diff_data, main="PACF of Differenced RSXFSN", lag.max=50)

The ACF displays an abrupt cut-off after lag 12, and the PACF gradually decays, which is indicative of a Moving Average model.

Fitting a SARIMA Model

# Fit a seasonal ARIMA model manually
# Non-seasonal part: ARIMA(0,0,2), Seasonal part: ARIMA(0,2,12)[12]
adjusted_arima_model <- Arima(combined_diff_data, order = c(0, 0, 2), seasonal = c(0, 0, 12))

# Summary of the adjusted ARIMA model
summary(adjusted_arima_model)
Series: combined_diff_data 
ARIMA(0,0,2) with non-zero mean 

Coefficients:
          ma1      ma2      mean
      -0.1526  -0.4173   12.7487
s.e.   0.0854   0.0849  749.6410

sigma^2 = 3.38e+08:  log likelihood = -1268.63
AIC=2545.26   AICc=2545.63   BIC=2556.17

Training set error measures:
                    ME     RMSE      MAE     MPE     MAPE      MASE        ACF1
Training set -22.10046 18139.64 11832.41 56.0421 156.7261 0.5800389 0.001788122
# Diagnostic checking of the adjusted model
checkresiduals(adjusted_arima_model)

    Ljung-Box test

data:  Residuals from ARIMA(0,0,2) with non-zero mean
Q* = 4.2086, df = 8, p-value = 0.8378

Model df: 2.   Total lags used: 10

# Use tsdiag to generate diagnostic plots
tsdiag(adjusted_arima_model)

# Fit a seasonal ARIMA model
# Non-seasonal part: ARIMA(2,1,0), Seasonal part: ARIMA(1,1,1)[12]
adjusted_arima_model_2 <- Arima(combined_diff_data, order = c(0, 0, 12), seasonal = c(0, 0, 10))

# Summary of the adjusted ARIMA model
summary(adjusted_arima_model_2)
Series: combined_diff_data 
ARIMA(0,0,12) with non-zero mean 

Coefficients:
          ma1      ma2     ma3      ma4      ma5     ma6      ma7      ma8     ma9    ma10
      -0.2489  -0.1880  0.1805  -0.1458  -0.0933  0.2216  -0.1103  -0.1227  0.3371  0.0174
s.e.   0.0937   0.0997  0.1094   0.0942   0.0998  0.1117   0.0939   0.0954  0.1138  0.0935
         ma11     ma12      mean
      -0.2301  -0.6175  156.1416
s.e.   0.1065   0.1106  285.6890

sigma^2 = 216418099:  log likelihood = -1246.91
AIC=2521.81   AICc=2526.1   BIC=2559.99

Training set error measures:
                   ME     RMSE     MAE      MPE     MAPE      MASE        ACF1
Training set 203.7765 13839.09 9898.97 12.37666 183.9934 0.4852594 -0.04652619
# Diagnostic checking of the adjusted model
checkresiduals(adjusted_arima_model_2)

    Ljung-Box test

data:  Residuals from ARIMA(0,0,12) with non-zero mean
Q* = 11.244, df = 3, p-value = 0.01048

Model df: 12.   Total lags used: 15

# Use tsdiag to generate diagnostic plots
tsdiag(adjusted_arima_model_2)

The residuals’ ACF and PACF plots indicate that the model’s residuals are mostly uncorrelated, suggesting a good fit, though the SARIMA(0,0,12)(0,0,10) is slightly better with an AIC of 2521.81 versus 2545.26. While the SARIMA model captures the seasonality and general trend, it may not fully account for the extreme fluctuations seen in the historical data. For better predictions, it might be necessary to explore other models or include additional explanatory variables.

Investigating GARCH Model

Investigating Squared Residuals to Justify GARCH Model

# Calculate returns
returns <- diff(log(retail_sales_data$RSXFSN))

# Square the returns
squared_returns <- returns^2

# Create a data frame for plotting
squared_returns_data <- data.frame(DATE = retail_sales_data$DATE[-1], Squared_Returns = squared_returns)

# Plot the squared returns
library(ggplot2)
ggplot(data = squared_returns_data, aes(x = DATE, y = Squared_Returns)) +
  geom_line(color = "blue") +
  labs(title = "Squared Returns of Monthly Retail Sales",
       x = "Date",
       y = "Squared Returns") +
  theme_minimal()

The squared returns of the monthly sales data shows much periodic volatility, which indicates that the data is a strong candidate for the GARCH model.

ACF and PACF of Squared Residuals

# Calculate residuals
arima_residuals <- residuals(adjusted_arima_model_2)

# Square the residuals to focus on volatility
squared_arima_residuals <- arima_residuals^2

par(mar=c(5, 5, 4, 2) + 0.1)
# Plot ACF of squared residuals
Acf(squared_arima_residuals, main="ACF of Squared Residuals")


# Plot PACF of squared residuals
Pacf(squared_arima_residuals, main="PACF of Squared Residuals")

The ACF of the squared residuals shows significant autocorrelation at various lags, suggesting periods of high volatility followed by high volatility and periods of low volatility follow periods of low volatility. This pattern is indicative of volatility clustering, a characteristic of financial time series data. The presence of significant autocorrelation in squared residuals also suggests nonlinearity in variance, highlighting a need for models like GARCH.

Fitting the GARCH Model to seasonally differenced data plus an additional order of differencing

combined_xts <- xts(combined_diff_data, order.by = as.Date(time(combined_diff_data)))

# Fit the SARIMA model
# Extract residuals from the SARIMA model
sarima_residuals <- residuals(adjusted_arima_model_2)

# Extract dates from the combined_xts
dates <- index(combined_xts)

# Convert SARIMA residuals to xts format
sarima_residuals_xts <- xts(sarima_residuals, order.by = dates)

# Fit a GARCH model on the SARIMA residuals
# Define a simple GARCH(1,1) model
garch_spec <- ugarchspec(
  variance.model = list(model = "sGARCH", garchOrder = c(1, 1)),
  mean.model = list(armaOrder = c(0, 0), include.mean = FALSE),
  distribution.model = "norm"
)

# Fit the GARCH model on SARIMA residuals
garch_fit <- ugarchfit(spec = garch_spec, data = sarima_residuals_xts)
Warning: 
rugarch-->warning: failed to invert hessian
# Summarize GARCH model fit
summary(garch_fit)
   Length     Class      Mode 
        1 uGARCHfit        S4 
# Evaluate the Combined Model
# Check residuals of the SARIMA model
checkresiduals(adjusted_arima_model_2)

    Ljung-Box test

data:  Residuals from ARIMA(0,0,12) with non-zero mean
Q* = 11.244, df = 3, p-value = 0.01048

Model df: 12.   Total lags used: 15

# Plot diagnostic plots for GARCH model
plot(garch_fit)

Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
1

Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
2

please wait...calculating quantiles...


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
3


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
4


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
5


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
6


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
7


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
8


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
9


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
10


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
11


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
12


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
0


# Check ACF of standardized residuals from the GARCH model
garch_residuals <- residuals(garch_fit, standardize = TRUE)

# Convert GARCH residuals to xts format, adjust for any differencing
garch_residuals_xts <- xts(garch_residuals, order.by = dates[1:length(garch_residuals)])  # Adjust index if necessary

# Plot ACF using PerformanceAnalytics
chart.ACFplus(garch_residuals_xts, main = "ACF of Standardized GARCH Residuals")


# Plot rolling volatility to assess dynamic volatility over time
chart.RollingPerformance(garch_residuals_xts, width = 12, FUN = "sd", main = "Rolling Volatility (Standard Deviation)")

The ACF and PACF of the Standardized Residuals show no significant spikes except for the first, indicating that the residuals are uncorrelated and resemble white noise. In the QQ plot, the points fall close to the 45-degree line along the center and top-right-most portion of the graph, albeit with significant deviations at the bottom tail.

# Set the maximum number of lags for the Ljung-Box test
max_lags <- 20

# Initialize a vector to store p-values
p_values <- numeric(max_lags)

# Calculate the Ljung-Box test p-values for each lag
for (lag in 1:max_lags) {
  lb_test <- Box.test(garch_residuals, lag = lag, type = "Ljung-Box", fitdf = 0)
  p_values[lag] <- lb_test$p.value
}

# Create a plot of p-values
plot(1:max_lags, p_values, type = "b", pch = 19, col = "blue",
     xlab = "Lag", ylab = "p-value",
     main = "Ljung-Box Test p-values for Standardized Residuals")
abline(h = 0.05, col = "red", lty = 2)  # Add a line at the 0.05 significance level


# Creating a dataframe for plotting
residuals_df <- data.frame(Residuals = as.numeric(garch_residuals))
# Specify the number of periods you want to forecast
forecast_horizon <- 12

# Forecast future values using the SARIMA model
sarima_forecast <- forecast(adjusted_arima_model_2, h = forecast_horizon)

# Plot SARIMA forecast
plot(sarima_forecast, main = "SARIMA Forecast")


# Step 4: Forecast using the GARCH model
garch_forecast <- ugarchforecast(garch_fit, n.ahead = forecast_horizon)

# Extract forecasted volatility (standard deviation) from the GARCH model
volatility_forecast <- sigma(garch_forecast)

# Print volatility forecast
print(volatility_forecast)
     1970-04-24
T+1    11949.97
T+2    11952.08
T+3    11954.19
T+4    11956.29
T+5    11958.39
T+6    11960.49
T+7    11962.58
T+8    11964.68
T+9    11966.77
T+10   11968.86
T+11   11970.94
T+12   11973.03
# Combine SARIMA forecast with GARCH volatility forecast
plot(sarima_forecast, main = "Forecasted Mean with SARIMA", xlab = "Time", ylab = "Values")
lines(volatility_forecast, col = "red", lty = 2)

legend("topright", legend = c("SARIMA Mean", "GARCH Volatility"), col = c("blue", "red"), lty = 1:2)

AAPL Monthly Data 2016-2024

Load & Inspect the Data

# Load the data
aapl_monthly_data <- read.csv("~/Documents/GitHub/MA-641-Course-Project/AAPL_Monthly2016.csv")

# Convert the date column to Date type
aapl_monthly_data$Date <- as.Date(aapl_monthly_data$Date, format="%Y-%m-%d")

# Inspect the data
head(aapl_monthly_data)
summary(aapl_monthly_data)
      Date                 Open             High             Low             Close       
 Min.   :2016-01-01   Min.   : 23.49   Min.   : 24.72   Min.   : 22.37   Min.   : 23.43  
 1st Qu.:2018-02-01   1st Qu.: 41.74   1st Qu.: 44.30   1st Qu.: 40.16   1st Qu.: 41.95  
 Median :2020-03-01   Median : 71.56   Median : 81.06   Median : 64.09   Median : 73.45  
 Mean   :2020-03-01   Mean   : 94.47   Mean   :101.04   Mean   : 88.97   Mean   : 95.93  
 3rd Qu.:2022-04-01   3rd Qu.:148.99   3rd Qu.:157.50   3rd Qu.:138.27   3rd Qu.:149.80  
 Max.   :2024-05-01   Max.   :196.24   Max.   :199.62   Max.   :187.45   Max.   :196.45  
   Adj.Close          Volume         
 Min.   : 21.39   Min.   :9.697e+08  
 1st Qu.: 39.72   1st Qu.:1.676e+09  
 Median : 71.54   Median :2.240e+09  
 Mean   : 93.98   Mean   :2.320e+09  
 3rd Qu.:147.50   3rd Qu.:2.801e+09  
 Max.   :195.41   Max.   :6.280e+09  

About the Data:

  • 101 data points spanning from 01/01/16 to 05/01/24
  • Data includes the monthly open, high, low, close, and adjusted close prices of the apple stock

Create a Time Series Object

# Create a time series object
aaplmonthly_ts <- ts(aapl_monthly_data$Close, start=c(2016, 01), end = c(2024, 05), frequency=12) 

Descripvtive Analysis

# Descriptive Analysis
plot(aaplmonthly_ts, main="Monthly Apple Stock Prices", ylab="Close Price", xlab="Time")

summary(aaplmonthly_ts)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  23.43   41.95   73.45   95.93  149.80  196.45 
boxplot(aaplmonthly_ts ~ cycle(aaplmonthly_ts), main="Seasonal Boxplot of Monthly Apple Stock Prices", ylab="Close Price")

Time Series Plot:

  • There is a clear upward trend in Apple stock prices over the period. The prices show a substantial increase, particularly starting around 2019.
  • There is visible volatility in the stock prices, with fluctuations becoming more pronounced in the later years.
  • The increased volatility may imply higher risk for investors, as the stock prices have larger swings.

Summary:

  • The mean and median values suggest that the central tendency of the stock prices is around 73 to 96.
  • The range indicates that the stock price has varied significantly over the period.

Seasonal Boxplot:

  • The presence of seasonality suggests that certain months tend to have higher or lower stock prices consistently, which can be crucial for seasonal trading strategies.
  • The seasonal boxplot reveals minor monthly patterns and variability, suggesting that seasonality should be considered in trading strategies and risk

ACF, PACF, & EACF Plots

# ACF and PACF Plots
par(mar=c(5, 5, 4, 2) + 0.1)
acf(aaplmonthly_ts, main="ACF of Monthly Apple Stock Prices", lag.max = 72)

pacf(aaplmonthly_ts, main="PACF of Monthly Apple Stock Prices", lag.max = 72)

eacf(aaplmonthly_ts)
AR/MA
  0 1 2 3 4 5 6 7 8 9 10 11 12 13
0 x x x x x x x x x x x  x  x  x 
1 o x o o o o o o o o o  o  o  o 
2 x x o o o o o o x o o  o  o  o 
3 o o o o o o o o o o o  o  o  o 
4 x o o o o o o o o o o  o  o  o 
5 o o o o o o o o o o o  o  o  o 
6 o o o o o o o o o o o  o  o  o 
7 o o o x o o o o o o o  o  o  o 

ACF Plot:

  • The gradual decay in the ACF indicates the presence of a trend component in the time series. The series is likely non-stationary.
  • Significant autocorrelations suggest that the data is not random and past values can help predict future values.
  • A high degree of positive autocorrelation at the first few lags implies momentum in the stock prices, which is common in financial time series.

PACF Plot:

  • The sharp drop after the first lag in the PACF suggests that an AR(1) model may be appropriate for capturing the relationship in the data.
  • The significant first lag indicates that the immediate past value has a strong influence on the current value, while the influence of values further in the past diminishes quickly.
  • This pattern supports the use of a simple autoregressive model, as the complexity beyond the first lag does not add much explanatory power.

ADF Test

# Augmented Dickey-Fuller Test
adf_test <- adf.test(aaplmonthly_ts, alternative="stationary")
print(adf_test)

    Augmented Dickey-Fuller Test

data:  aaplmonthly_ts
Dickey-Fuller = -2.3411, Lag order = 4, p-value = 0.4353
alternative hypothesis: stationary
  • Since the p-value is greater than 0.05, we fail to reject the null hypothesis that the time series has a unit root. This indicates that the series is non-stationary.
  • The non-stationarity observed from the ADF test results implies that differencing the time series is necessary to achieve stationarity.
# Differencing the series if it is not stationary
if (adf_test$p.value > 0.05) {
  ts_data_diff <- diff(aaplmonthly_ts, differences=1)
  adf_test_diff <- adf.test(ts_data_diff, alternative="stationary")
  print(adf_test_diff)
  
  # Update the time series data to the differenced series
  aaplmonthly_ts <- ts_data_diff
}
Warning: p-value smaller than printed p-value

    Augmented Dickey-Fuller Test

data:  ts_data_diff
Dickey-Fuller = -5.0114, Lag order = 4, p-value = 0.01
alternative hypothesis: stationary
  • Since the p-value is less than 0.05, we reject the null hypothesis that the time series has a unit root. This indicates that the differenced series is stationary.
  • With the differenced series being stationary, it is now suitable for fitting ARIMA models.
# Time Series Plot after Differencing
plot(aaplmonthly_ts, main="Monthly Apple Stock Prices", ylab="Close Price", xlab="Time")

# ACF and PACF Plots
par(mar=c(5, 5, 4, 2) + 0.1)

acf(aaplmonthly_ts, main="ACF of Monthly Apple Stock Prices", lag.max = 72)

pacf(aaplmonthly_ts, main="PACF of Monthly Apple Stock Prices", lag.max = 72)

eacf(aaplmonthly_ts)
AR/MA
  0 1 2 3 4 5 6 7 8 9 10 11 12 13
0 o x o o o o o o x o o  o  o  o 
1 o x o o o o o o x o o  o  o  o 
2 o o o o o o o o o o o  o  o  o 
3 o o o o o o o o o o o  o  o  o 
4 x o o o o o o o o o o  o  o  o 
5 x o o o o o o o o o o  o  o  o 
6 x x o o o o o o o o o  o  o  o 
7 x x o o x o x o o o o  o  o  o 
  • We can see that after differencing the time-series appears to be stationary.

ACF Plot:

  • Exponential decay, suggests an AR model.
  • Spike at certain lags and then no significant autocorrelation indicates an MA model.
  • Lag 1: Strong positive autocorrelation, possibly suggesting an MA(1) component.
  • Further Lags: Gradual decay suggests potential AR component, but initial spikes may also indicate an MA component.

PACF Plot:

  • Lag 1: A significant spike, suggesting an AR(1) component.
  • Further Lags: The lack of significant spikes after the initial ones implies no strong additional AR terms.

EACF Plot:

  • ARIMA(1,0,1): Due to the significant spike at lag 1 in both ACF and PACF plots.
  • ARIMA(0,0,1): Due to the initial spikes in the ACF and a quickly decaying PACF.
  • ARIMA(1,0,0): Due to the AR component suggested by PACF.
  • ARIMA(2,0,1) or ARIMA(1,0,2): EACF indicates potential combined AR and MA terms.

Fit AR, MA, and ARMA Models

AR Model

# Fit AR model
ar_model <- Arima(aaplmonthly_ts, order=c(2,0,0))
summary(ar_model)
Series: aaplmonthly_ts 
ARIMA(2,0,0) with non-zero mean 

Coefficients:
         ar1      ar2    mean
      0.0409  -0.2708  1.6476
s.e.  0.0988   0.0980  0.6883

sigma^2 = 73.24:  log likelihood = -355.13
AIC=718.27   AICc=718.69   BIC=728.69

Training set error measures:
                       ME     RMSE     MAE      MPE     MAPE      MASE         ACF1
Training set -0.000308276 8.428628 6.23919 507.0341 563.7521 0.7036177 -0.001614169
  • AR(1) Coefficient=0.0409, is a small positive value close to zero which suggests a weak positive correlation with the immediate past month’s value
  • AR(2) Coefficient=-0.2708, is a negative value which suggests that the price two months ago has a moderate inverse relationship with the current month’s price
  • Mean=1.6476, the average level of the series after removing the autoregressive effects
  • The AR(1) coefficient is small, while the AR(2) coefficient is moderate and negative, suggesting some complexity in how past values relate to current values
  • The model accounts for the influence of two previous months’ prices, capturing both immediate and delayed effects
  • The variance is relatively high, which may indicate substantial unexplained variability
  • RMSE and MAE are moderate, indicating that the model has reasonable accuracy but could be improved
  • High MPE and MAPE suggest some forecasts might be significantly off from actual values
Residual Analysis
# Perform diagnostics for AR(2)
par(mar=c(5, 5, 4, 2) + 0.1)
tsdiag(ar_model, gof.lag = 10, main = "Diagnostics for AR(2)")

checkresiduals(ar_model)

    Ljung-Box test

data:  Residuals from ARIMA(2,0,0) with non-zero mean
Q* = 23.044, df = 18, p-value = 0.1889

Model df: 2.   Total lags used: 20

# Q-Q plot for AR(2)
residuals_ar2 <- residuals(ar_model)
qqnorm(residuals_ar2, main = "Q-Q Plot of Residuals for AR(2)")
qqline(residuals_ar2, col = "red")

Q-Q Plot:

  • The points in the middle of the plot are closely aligned with the red line, indicating that the central residuals are approximately normally distributed.
  • There is some deviation at the tails of the distribution, with points falling off the line, suggesting the presence of some outliers or non-normality in the extreme values.
  • The Q-Q plot indicates that while most residuals follow a normal distribution, the extreme values do not. This is common in financial data where extreme values (volatility clusters) are not uncommon.

Residuals vs. Time Plot:

  • The residuals appear to be randomly scattered around zero with no discernible pattern over time.
  • This randomness suggests that the AR(2) model has effectively captured the linear patterns in the data, leaving white noise residuals.

ACF of Residuals:

  • The autocorrelation function (ACF) of the residuals shows that most spikes are within the confidence bands, indicating no significant autocorrelations.
  • Lack of significant autocorrelation implies that there are no patterns left unexplained by the AR(2) model.

Histogram of Residuals:

  • The histogram with the superimposed normal curve suggests a somewhat normal distribution of residuals, although there might be slight skewness.
  • This further supports the finding from the Q-Q plot that the residuals are approximately normal, but with some deviations at the tails.

Ljung-Box Test:

  • With a p-value of 0.1889, we fail to reject the null hypothesis. This indicates that the residuals do not exhibit significant autocorrelation, suggesting that the AR(2) model fits the data well in terms of capturing the temporal dependencies.

MA Model

# Fit MA model
ma_model <- Arima(aaplmonthly_ts, order=c(0,0,2))
summary(ma_model)
Series: aaplmonthly_ts 
ARIMA(0,0,2) with non-zero mean 

Coefficients:
         ma1      ma2    mean
      0.0231  -0.2775  1.6525
s.e.  0.0979   0.0971  0.6327

sigma^2 = 73.16:  log likelihood = -355.09
AIC=718.17   AICc=718.59   BIC=728.59

Training set error measures:
                       ME     RMSE     MAE      MPE     MAPE      MASE      ACF1
Training set -0.006781185 8.424279 6.24754 520.9368 585.7699 0.7045594 0.0114845
  • The small MA(1) coefficient suggests a weak impact of the error from one period ago, while the moderate negative MA(2) coefficient indicates a more noticeable inverse relationship with errors from two periods ago.
  • The variance (sigma^2) is moderate, consistent with the AR(2) model, suggesting a similar level of unexplained volatility.
  • RMSE and MAE are slightly lower than those of the AR(2) model, indicating that the MA(2) model may fit the data slightly better in terms of absolute error metrics.
  • The AIC and BIC values are very similar to those of the AR(2) model, suggesting that both models are comparable in fit.
  • The slightly lower AIC suggests the MA(2) model might be marginally better in terms of balancing model complexity and goodness of fit.
Residual Analysis
# Perform diagnostics for MA(2)
par(mar=c(5, 5, 4, 2) + 0.1)
tsdiag(ma_model, gof.lag = 10, main = "Diagnostics for MA(2)")

checkresiduals(ma_model)

    Ljung-Box test

data:  Residuals from ARIMA(0,0,2) with non-zero mean
Q* = 24.159, df = 18, p-value = 0.1499

Model df: 2.   Total lags used: 20

# Q-Q plot for MA(2)
residuals_ma2 <- residuals(ma_model)
qqnorm(residuals_ma2, main = "Q-Q Plot of Residuals for MA(2)")
qqline(residuals_ma2, col = "red")

Q-Q Plot:

  • The plot shows that the residuals closely follow the red line in the middle section, suggesting that the residuals are approximately normally distributed.
  • However, there are deviations at the tails, indicating potential issues with normality at the extremes (outliers).

Residuals vs. Time Plot:

  • The residuals appear to be scattered randomly around zero, indicating no obvious patterns or trends.
  • This suggests that the model has captured most of the structure in the data.

ACF of Residuals:

  • Most of the spikes are within the blue dashed lines, indicating that the residuals do not exhibit significant autocorrelation.
  • A few spikes slightly exceed the bounds, which may indicate some remaining autocorrelation, but it’s not substantial.

Histogram of Residuals:

  • The residuals appear to follow a bell-shaped curve, which suggests approximate normality.
  • There is a slight skewness, as seen by the mismatch between the histogram and the normal curve.

Ljung-Box Test:

  • The p-value is 0.1499, which is greater than 0.05. This indicates that there is no significant autocorrelation in the residuals. The model’s residuals can be considered independently distributed.

ARIMA(1,1,1) Model

# Fit ARMA(1,1,1) model
arma_model1 <- Arima(aaplmonthly_ts, order=c(1,1,1))
summary(arma_model1)
Series: aaplmonthly_ts 
ARIMA(1,1,1) 

Coefficients:
         ar1      ma1
      0.0413  -1.0000
s.e.  0.1034   0.0308

sigma^2 = 78.94:  log likelihood = -357.98
AIC=721.96   AICc=722.21   BIC=729.74

Training set error measures:
                    ME     RMSE      MAE     MPE     MAPE      MASE          ACF1
Training set 0.5179315 8.750795 6.505048 433.929 441.6441 0.7335995 -0.0008596899
  • The AR coefficient is weak, indicating a limited effect of past values on current values. The MA coefficient is very strong, indicating significant correction based on past errors.
  • The differencing part of the ARIMA model suggests that the data has been transformed to achieve stationarity, which might explain why the AR component is weak.
  • The variance of the residuals is moderate, suggesting some unexplained variability in the data.
  • RMSE and MAE are higher than in AR(2) and MA(2), indicating less precise predictions.
  • The AIC and BIC values suggest this model might not be the best fit compared to simpler models like AR(2) and MA(2), which had lower AIC/BIC values.
Residual Analysis
# Perform diagnostics for ARIMA(1,1,1)
par(mar=c(5, 5, 4, 2) + 0.1)
tsdiag(arma_model1, gof.lag = 10, main = "Diagnostics for ARIMA(1,1,1)")

checkresiduals(arma_model1)

    Ljung-Box test

data:  Residuals from ARIMA(1,1,1)
Q* = 44.611, df = 18, p-value = 0.0004715

Model df: 2.   Total lags used: 20

# Q-Q plot for ARIMA(1,1,1)
residuals_arma111 <- residuals(arma_model1)
qqnorm(residuals_arma111, main = "Q-Q Plot of Residuals for ARIMA(1,1,1)")
qqline(residuals_arma111, col = "red")

Q-Q Plot:

  • The residuals are mostly aligned with the straight line, suggesting that they are approximately normally distributed.
  • However, there are some deviations at both tails, indicating potential issues with extreme values or heavy tails.
  • The plot indicates that while most of the residuals follow a normal distribution, there may be some extreme values (outliers) that deviate from this assumption.

Residuals vs. Time Plot:

  • The residuals appear to be centered around zero, which is a good sign for unbiased predictions.
  • There are some visible spikes and variations over time, which could indicate non-constant variance or potential patterns not captured by the model.

ACF of Residuals:

  • The ACF values are mostly within the blue dashed lines (confidence intervals), suggesting that the residuals do not exhibit significant autocorrelation.
  • This indicates that the ARIMA(1,1,1) model has successfully captured most of the autocorrelation structure in the data.

Histogram of Residuals:

  • The distribution appears to be approximately normal, but with slight skewness and kurtosis, as indicated by the histogram.
  • There are some residuals on the tails that are further away from the normal curve, which could affect model accuracy for extreme values.

Ljung-Box Test:

  • The low p-value suggests that there is significant autocorrelation present in the residuals. This indicates that the ARIMA(1,1,1) model may not have captured all the autocorrelation in the data, leading to potential improvement in model fit.

ARIMA(2,1,1) Model

# ARMA(2,1,1) Model
arma_model2 <- Arima(aaplmonthly_ts, order=c(2,1,1))
summary(arma_model2)
Series: aaplmonthly_ts 
ARIMA(2,1,1) 

Coefficients:
         ar1      ar2      ma1
      0.0486  -0.2632  -1.0000
s.e.  0.0996   0.0988   0.0377

sigma^2 = 74.02:  log likelihood = -354.58
AIC=717.16   AICc=717.59   BIC=727.54

Training set error measures:
                    ME     RMSE      MAE      MPE     MAPE      MASE        ACF1
Training set 0.6253754 8.429532 6.225648 78.44247 127.6236 0.7020905 -0.01202426
  • The AR coefficients show a mixed impact, with a weak positive effect from the last period and a moderate negative effect from two periods ago. The strong MA(1) term suggests that recent errors are heavily corrected, which may smooth the series too aggressively.
  • The variance of the residuals is moderate, indicating a fair amount of explained variability. The error measures (RMSE and MAE) suggest that the model provides reasonably accurate predictions, although there are still areas for improvement.
  • The AIC and BIC values are relatively low, indicating a good fit compared to other models. The log likelihood is also higher, supporting this conclusion.
  • The ARIMA(2,1,1) model captures the data dynamics well, with strong correction for past errors and a reasonable account of past values. The model is effective in handling the data’s structure and trends, as indicated by the low error measures and ACF1.
Residual Analysis
# Perform diagnostics for ARIMA(2,1,1)
par(mar=c(5, 5, 4, 2) + 0.1)
tsdiag(arma_model2, gof.lag = 10, main = "Diagnostics for ARIMA(2,1,1)")

checkresiduals(arma_model2)

    Ljung-Box test

data:  Residuals from ARIMA(2,1,1)
Q* = 23.957, df = 17, p-value = 0.1206

Model df: 3.   Total lags used: 20

# Q-Q plot for ARIMA(2,1,1)
residuals_arma211 <- residuals(arma_model2)
qqnorm(residuals_arma211, main = "Q-Q Plot of Residuals for ARIMA(2,1,1)")
qqline(residuals_arma211, col = "red")

Q-Q Plot:

  • The residuals are close to the line, especially in the middle range, indicating that they are approximately normally distributed.
  • The tails deviate slightly from the line, suggesting potential outliers or non-normality in the extremes. This is common in financial data.

Residuals vs. Time Plot:

  • The residuals fluctuate around zero, indicating that the model has captured the trend well.
  • The variance of residuals appears constant over time, which satisfies one of the assumptions of ARIMA modeling.
  • There are no obvious patterns, suggesting the model is capturing most of the signal.

ACF of Residuals:

  • The majority of the autocorrelation values fall within the blue confidence bands, indicating no significant autocorrelation.
  • This suggests that the model has effectively captured the autocorrelations in the data.

Histogram of Residuals:

  • The histogram shows a bell-shaped curve, with some deviation at the tails, which is typical for time series data.
  • The overlaying normal curve fits reasonably well, suggesting residuals are approximately normally distributed.

Ljung-Box Test:

  • The p-value is greater than 0.05, indicating that we fail to reject the null hypothesis of no autocorrelation in the residuals. This means the residuals are likely random, supporting the model’s adequacy.

ARIMA(2,1,2) Model

# ARMA(2,1,2) Model
arma_model3 <- Arima(aaplmonthly_ts, order=c(2,1,2))
summary(arma_model3)
Series: aaplmonthly_ts 
ARIMA(2,1,2) 

Coefficients:
         ar1      ar2      ma1      ma2
      0.0375  -0.2628  -0.9880  -0.0120
s.e.  0.4098   0.1004   0.4284   0.4267

sigma^2 = 74.8:  log likelihood = -354.58
AIC=719.16   AICc=719.8   BIC=732.13

Training set error measures:
                    ME     RMSE      MAE      MPE     MAPE      MASE        ACF1
Training set 0.6240689 8.429788 6.223491 79.15774 126.6565 0.7018472 -0.01277316
  • The AR(2) term seems significant, while the AR(1) and MA(2) terms are less impactful. The MA(1) term is strong, suggesting reliance on correcting the previous period’s error.
  • The residual variance (sigma^2) is slightly higher than desired, indicating some unexplained variability. The ACF1 is close to zero, which is positive, indicating little remaining autocorrelation.
  • Compared to the ARIMA(2,1,1) model, this model has slightly higher AIC and BIC, suggesting it might not fit as well. However, the performance metrics (RMSE, MAE) are competitive, indicating this model is also a valid candidate.
  • While the error measures (MAPE, MPE) show some prediction errors, the model captures the general trend well. Improvements could be made by refining the model or testing alternative specifications.
Residual Analysis
# Perform diagnostics for ARIMA(2,1,2)
par(mar=c(5, 5, 4, 2) + 0.1)
tsdiag(arma_model3, gof.lag = 10, main = "Diagnostics for ARIMA(2,1,2)")

checkresiduals(arma_model3)

    Ljung-Box test

data:  Residuals from ARIMA(2,1,2)
Q* = 23.916, df = 16, p-value = 0.09136

Model df: 4.   Total lags used: 20

# Q-Q plot for ARIMA(2,1,2)
residuals_arma212 <- residuals(arma_model3)
qqnorm(residuals_arma212, main = "Q-Q Plot of Residuals for ARIMA(2,1,2)")
qqline(residuals_arma212, col = "red")

Q-Q Plot:

  • The residuals are close to the line, especially in the middle range, indicating that they are approximately normally distributed.
  • The tails deviate slightly from the line, suggesting potential outliers or non-normality in the extremes. This is common in financial data.

Residuals vs. Time Plot:

  • The residuals fluctuate around zero, indicating that the ARIMA(2,1,2) model has successfully captured the main structure of the data.
  • There are no obvious patterns or trends visible, suggesting that the model accounts well for the systematic components of the time series.
  • The model appears to capture the dynamics of the data well, with residuals that resemble white noise.

ACF of Residuals:

  • Most autocorrelation values lie within the blue dashed confidence bounds, which suggests that the residuals are uncorrelated.
  • The lack of significant autocorrelation indicates that the model has effectively captured the autocorrelation structure of the series, resulting in residuals that are close to white noise.

Histogram of Residuals:

  • The residuals show a distribution that is fairly symmetric, though there might be some skewness or kurtosis.
  • The residuals’ distribution is fairly normal but with slight deviations, likely due to outliers or model imperfections.

Ljung-Box Test:

  • Since the p-value is greater than 0.05, we fail to reject the null hypothesis of no autocorrelation, suggesting that the residuals are indeed white noise.

GARCH Models

# Create a time series object
aaplmonthly_ts2 <- ts(aapl_monthly_data$Close, start=c(2016, 01), end = c(2024, 05), frequency=12) 
# Calculate returns for modeling
returns <- diff(log(aaplmonthly_ts2))
returns <- returns[!is.na(returns)]
plot(returns, main="Monthly Apple Stock Prices", ylab="Close Price", xlab="Time", type="l")

# Specify GARCH(1,1) model
spec_garch <- ugarchspec(variance.model = list(model = "sGARCH", garchOrder = c(1, 1)),
                         mean.model = list(armaOrder = c(1, 0)), 
                         distribution.model = "norm")

fit_garch <- ugarchfit(spec = spec_garch, data = returns)

# Display the fit summary
fit_garch

*---------------------------------*
*          GARCH Model Fit        *
*---------------------------------*

Conditional Variance Dynamics   
-----------------------------------
GARCH Model : sGARCH(1,1)
Mean Model  : ARFIMA(1,0,0)
Distribution    : norm 

Optimal Parameters
------------------------------------
        Estimate  Std. Error  t value Pr(>|t|)
mu      0.020696    0.008198  2.52440  0.01159
ar1     0.009283    0.100840  0.09206  0.92665
omega   0.000212    0.000204  1.03801  0.29927
alpha1  0.000000    0.014482  0.00000  1.00000
beta1   0.969597    0.051349 18.88262  0.00000

Robust Standard Errors:
        Estimate  Std. Error   t value Pr(>|t|)
mu      0.020696    0.006649  3.112732 0.001854
ar1     0.009283    0.103105  0.090038 0.928257
omega   0.000212    0.000379  0.558168 0.576730
alpha1  0.000000    0.005313  0.000000 1.000000
beta1   0.969597    0.059723 16.234816 0.000000

LogLikelihood : 108.877 

Information Criteria
------------------------------------
                    
Akaike       -2.0775
Bayes        -1.9473
Shibata      -2.0822
Hannan-Quinn -2.0248

Weighted Ljung-Box Test on Standardized Residuals
------------------------------------
                        statistic p-value
Lag[1]                  0.0001857  0.9891
Lag[2*(p+q)+(p+q)-1][2] 1.2346095  0.5948
Lag[4*(p+q)+(p+q)-1][5] 2.4164966  0.5903
d.o.f=1
H0 : No serial correlation

Weighted Ljung-Box Test on Standardized Squared Residuals
------------------------------------
                        statistic p-value
Lag[1]                      1.449  0.2287
Lag[2*(p+q)+(p+q)-1][5]     3.745  0.2876
Lag[4*(p+q)+(p+q)-1][9]     6.376  0.2572
d.o.f=2

Weighted ARCH LM Tests
------------------------------------
            Statistic Shape Scale P-Value
ARCH Lag[3]     3.543 0.500 2.000 0.05978
ARCH Lag[5]     3.661 1.440 1.667 0.20717
ARCH Lag[7]     5.696 2.315 1.543 0.16300

Nyblom stability test
------------------------------------
Joint Statistic:  1.4525
Individual Statistics:              
mu     0.07109
ar1    0.14752
omega  0.14307
alpha1 0.12991
beta1  0.14386

Asymptotic Critical Values (10% 5% 1%)
Joint Statistic:         1.28 1.47 1.88
Individual Statistic:    0.35 0.47 0.75

Sign Bias Test
------------------------------------


Adjusted Pearson Goodness-of-Fit Test:
------------------------------------
  group statistic p-value(g-1)
1    20      20.4       0.3709
2    30      21.8       0.8284
3    40      34.4       0.6796
4    50      42.0       0.7504


Elapsed time : 0.04331684 
# Specify GARCH(1,1) model
spec_garch <- ugarchspec(variance.model = list(model = "sGARCH", garchOrder = c(1, 1)),
                         mean.model = list(armaOrder = c(2, 1)), 
                         distribution.model = "norm")

fit_garch <- ugarchfit(spec = spec_garch, data = returns)

# Display the fit summary
fit_garch

*---------------------------------*
*          GARCH Model Fit        *
*---------------------------------*

Conditional Variance Dynamics   
-----------------------------------
GARCH Model : sGARCH(1,1)
Mean Model  : ARFIMA(2,0,1)
Distribution    : norm 

Optimal Parameters
------------------------------------
        Estimate  Std. Error  t value Pr(>|t|)
mu      0.020739    0.005744  3.61058 0.000306
ar1     0.604229    0.341075  1.77154 0.076471
ar2    -0.151955    0.108878 -1.39564 0.162824
ma1    -0.610786    0.339011 -1.80167 0.071598
omega   0.000208    0.000238  0.87143 0.383518
alpha1  0.000000    0.013219  0.00000 1.000000
beta1   0.968842    0.047477 20.40660 0.000000

Robust Standard Errors:
        Estimate  Std. Error  t value Pr(>|t|)
mu      0.020739    0.005612  3.69541 0.000220
ar1     0.604229    0.323349  1.86866 0.061671
ar2    -0.151955    0.095674 -1.58826 0.112228
ma1    -0.610786    0.293617 -2.08021 0.037506
omega   0.000208    0.000316  0.65791 0.510598
alpha1  0.000000    0.003947  0.00000 1.000000
beta1   0.968842    0.051773 18.71330 0.000000

LogLikelihood : 110.5264 

Information Criteria
------------------------------------
                    
Akaike       -2.0705
Bayes        -1.8882
Shibata      -2.0795
Hannan-Quinn -1.9967

Weighted Ljung-Box Test on Standardized Residuals
------------------------------------
                         statistic p-value
Lag[1]                   0.0007236  0.9785
Lag[2*(p+q)+(p+q)-1][8]  0.7800872  1.0000
Lag[4*(p+q)+(p+q)-1][14] 1.9624525  0.9999
d.o.f=3
H0 : No serial correlation

Weighted Ljung-Box Test on Standardized Squared Residuals
------------------------------------
                        statistic p-value
Lag[1]                      2.977 0.08444
Lag[2*(p+q)+(p+q)-1][5]     4.546 0.19337
Lag[4*(p+q)+(p+q)-1][9]     6.847 0.21233
d.o.f=2

Weighted ARCH LM Tests
------------------------------------
            Statistic Shape Scale P-Value
ARCH Lag[3]     2.326 0.500 2.000  0.1273
ARCH Lag[5]     2.329 1.440 1.667  0.4030
ARCH Lag[7]     4.181 2.315 1.543  0.3212

Nyblom stability test
------------------------------------
Joint Statistic:  2.2869
Individual Statistics:              
mu     0.14030
ar1    0.06721
ar2    0.04291
ma1    0.07467
omega  0.13026
alpha1 0.10397
beta1  0.13095

Asymptotic Critical Values (10% 5% 1%)
Joint Statistic:         1.69 1.9 2.35
Individual Statistic:    0.35 0.47 0.75

Sign Bias Test
------------------------------------


Adjusted Pearson Goodness-of-Fit Test:
------------------------------------
  group statistic p-value(g-1)
1    20      27.6     0.091435
2    30      40.4     0.077606
3    40      47.2     0.172404
4    50      77.0     0.006497


Elapsed time : 0.06607103 

Model Fit:

  • The GARCH(1,1) with ARFIMA(1,0,0) mean equation provides a reasonable fit to the data. The high significance of the \(\beta_1\) parameter highlights the importance of past volatility in explaining current volatility.
  • The absence of significant serial correlation in both raw and squared residuals indicates that the model captures the autocorrelation and volatility clustering effectively.
  • The p-values from the diagnostic tests suggest that the residuals approximate a normal distribution, making the model suitable for the data.
  • The stability of individual parameters suggests the model’s robustness over time, though there is a slight indication of overall instability.
  • The model is useful for forecasting future volatility and capturing the volatility clustering typical in financial time series like stock prices.
# Plot diagnostics
plot(fit_garch)

Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
1

Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
2

please wait...calculating quantiles...


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
3


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
4


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
5


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
6


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
7


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
8


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
9


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
10


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
11


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
12


Make a plot selection (or 0 to exit): 

 1:   Series with 2 Conditional SD Superimposed
 2:   Series with 1% VaR Limits
 3:   Conditional SD (vs |returns|)
 4:   ACF of Observations
 5:   ACF of Squared Observations
 6:   ACF of Absolute Observations
 7:   Cross Correlation
 8:   Empirical Density of Standardized Residuals
 9:   QQ-Plot of Standardized Residuals
10:   ACF of Standardized Residuals
11:   ACF of Squared Standardized Residuals
12:   News-Impact Curve
0

News Impact Curve:

  • The curve is symmetrical, indicating that both positive and negative shocks of equal magnitude have a similar impact on volatility.
  • The U-shape shows that both positive and negative returns increase volatility equally, which is typical for symmetric GARCH models.

ACF of Squared Standardized Residuals:

  • Most of the autocorrelation values fall within the confidence bands, indicating no significant autocorrelation in the squared residuals.
  • This suggests that the GARCH model has successfully captured the volatility clustering in the data, meaning the model’s volatility structure is adequate.

ACF of Standardized Residuals:

  • The residuals appear to be white noise since most autocorrelations lie within the confidence bands.
  • This suggests the mean equation part of the ARFIMA-GARCH model has been well specified and captures the data’s dynamics effectively.

Q-Q Plot:

  • The points largely follow the line, indicating the residuals are approximately normally distributed. Some deviations at the tails might suggest potential fat tails.

Empirical Density of Standardized Residuals:

  • The residuals closely follow a normal distribution, implying that the model does not have significant misspecification in terms of distributional assumptions.

Cross-Correlations of Squared vs. Actual Observations:

  • Ideally, there should be no significant correlation, implying that the squared returns (proxy for volatility) do not show further predictable patterns.
  • The one significant bar indicates a potential additional pattern the model hasn’t captured.

ACF of Absolute Observations:

  • Absence of significant autocorrelations indicates that the GARCH model adequately captures volatility clustering.

ACF of Squared Observations:

  • The lack of significant autocorrelation implies that the model has captured the serial dependence in the volatility of the series.

ACF of Observations:

  • Lack of significant autocorrelation indicates that the mean model is capturing the dynamics effectively, suggesting an adequate ARFIMA fit.

Conditional Standard Deviation vs. Returns:

  • The plot reveals the model’s ability to track periods of high and low volatility. If the GARCH model is capturing the time-varying volatility adequately, the conditional SD should match periods of high returns variance.

Series with 2 Conditional SD Superimposed:

  • The red lines represent the 2 conditional standard deviations above and below the mean.
  • The model fits well, most of the data points should fall within these bounds, indicating that the model accurately captures the volatility in the data.

Series with 1% VaR Limits:

  • The green and red lines represent the upper and lower VaR limits, respectively.
  • Overall the model fits well, the returns rarely exceed these limits, indicating that the model provides a good estimate of the risk.

Forecasting

# Forecasting with the GARCH model
forecast_garch <- ugarchforecast(fit_garch, n.ahead=12)
plot(forecast_garch, which=1)  # Forecast series

  • The forecasted values are pretty close to the actual historical values towards the end of the time series
  • The the red line appears relatively stable compared to the historical series, indicating that the model expects the future returns to stabilize somewhat, with less extreme fluctuations than observed in the past.
  • The yellow bands widen as the forecast horizon extends, which is typical in time series forecasting. This widening indicates that uncertainty increases the further into the future we predict. The actual returns may deviate significantly from the forecasted line, especially as we move further into the forecast horizon.
  • Since the historical series ends within the red line and yellow bands, it suggests that the model is capturing the central tendency of the time series well. However, the increasing width of the bands highlights that while the model expects less volatility, there is still considerable uncertainty about future values.

Model Comparison

# Comparing Models using AIC and BIC
models <- list(ar_model, ma_model, arma_model1, arma_model2, arma_model3)
model_names <- c("AR", "MA", "ARIMA(1,1,1)", "ARIMA(2,1,1)", "ARIMA(2,1,2", "GARCH")

aic_values <- c(sapply(models, AIC), -2.0775)
bic_values <- c(sapply(models, BIC), -1.9473)

comparison <- data.frame(Model=model_names, AIC=aic_values, BIC=bic_values)
print(comparison)
  • Based on both AIC and BIC criteria, the GARCH model is the best-suited model for your data.
  • GARCH is often preferred for financial time series data where volatility clustering is present, as it models changing variance over time, which ARIMA models do not handle well.
  • The significantly lower AIC and BIC values for the GARCH model suggest it fits the data better, likely capturing patterns of volatility more effectively than the AR or ARIMA models.
LS0tCnRpdGxlOiAiUHJvamVjdCBXb3JrIgphdXRob3I6ICJLaW1iZXJsZXkgTWFsZG9uYWRvLCBCcmVuZGFuIEtlbm55LCBFbWlseSBTdSwgQnJpYW5uYSBDaXJpbGxvIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCgojIyMgTGlicmFyaWVzCgpgYGB7cn0KIyBMb2FkIG5lY2Vzc2FyeSBsaWJyYXJpZXMKbGlicmFyeShmb3JlY2FzdCkKbGlicmFyeSh0c2VyaWVzKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShyZWFkcikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHpvbykKbGlicmFyeShUU0EpCmxpYnJhcnkocnVnYXJjaCkKbGlicmFyeShmb3JlY2FzdCkKbGlicmFyeShQZXJmb3JtYW5jZUFuYWx5dGljcykKbGlicmFyeSh4dHMpCmxpYnJhcnkocXVhbnRtb2QpCmBgYAogCgojIyBGUkVEIE1vbnRobHkgUmV0YWlsIFNhbGVzCiMjIyBMb2FkICYgSW5zcGVjdCB0aGUgRGF0YQoKYGBge3J9CmZpbGVfcGF0aCA8LSAifi9Eb2N1bWVudHMvR2l0SHViL01BLTY0MS1Db3Vyc2UtUHJvamVjdC9TY3JhdGNoIFdvcmsvUlNYRlNOLmNzdiIKCnJldGFpbF9zYWxlc19kYXRhIDwtIHJlYWRfY3N2KGZpbGVfcGF0aCkKCiMgQ29udmVydCB0aGUgREFURSBjb2x1bW4gdG8gRGF0ZSB0eXBlCnJldGFpbF9zYWxlc19kYXRhJERBVEUgPC0gYXMuRGF0ZShyZXRhaWxfc2FsZXNfZGF0YSREQVRFLCBmb3JtYXQ9IiVZLSVtLSVkIikKYGBgCgoKVGhlIGZvbGxvd2luZyBkYXRhc2V0IGlzIHBhcnQgb2YgdGhlIEFkdmFuY2UgTW9udGhseSBSZXRhaWwgVHJhZGUgU3VydmVyeSBjb25kdWN0ZWQgYnkgdGhlIFUuUyBDZW5zdXMgQnVyZWF1LCByZXRyaWV2ZWQgZnJvbSBGUkVEIGFuZCBtZWFzdXJlcyB0aGUgcmV0YWlsIHRyYWRlIGFjdGl2aXR5IGluIHRoZSBVbml0ZWQgU3RhdGVzLiBJdCBwcm92aWRlcyBhbiBlYXJseSBlc3RpbWF0ZSBvZiBtb250aGx5IHNhbGVzIGZvciByZXRhaWwgYW5kIGZvb2Qgc2VydmljZSBjb21wYW5pZXMgY2FwdHVyaW5nIGNvbnN1bWVyIGRlbWFuZCBmb3IgZ29vZHMgYW5kIHNlcnZpY2VzLiAKClRoZSBSU1hGU04gZGF0YSBzZXJpZXMgbWVhc3VyZXMgdGhlIGRvbGxhciB2YWx1ZSBvZiBzYWxlcyBhbmQgaXMgcmVwb3J0ZWQgb24gbWlsbGlvbnMgb2YgZG9sbGFycy4gVGhpcyBkYXRhIGlzIG5vdCBzZWFzb25hbGx5IGFkanVzdGVkIGFuZCBpcyByZWxlYXNlZCBtb250aGx5LiBUaGUgcGVyaW9kIG9mIG9ic2VydmF0aW9uIGZvciB0aGlzIHByb2plY3Qgc3BhbnMgYSAxMCB5ZWFyIHBlcmlvZCBmcm9tIEphbnVhcnkgMjAxNCB0byBNYXkgMjAyNCwgdG90YWxpbmcgMTI2IG9ic2VydmF0aW9ucy4gCgoKCmBgYHtyfQpoZWFkKHJldGFpbF9zYWxlc19kYXRhKQpzdW1tYXJ5KHJldGFpbF9zYWxlc19kYXRhKQoKIyBDaGVjayB0aGUgbnVtYmVyIG9mIHJvd3MgaW4gdGhlIG9yaWdpbmFsIGRhdGFzZXQKbnVtX2RhdGFfcG9pbnRzIDwtIG5yb3cocmV0YWlsX3NhbGVzX2RhdGEpCmNhdCgiTnVtYmVyIG9mIGRhdGEgcG9pbnRzIGluIHRoZSBvcmlnaW5hbCBkYXRhc2V0OiIsIG51bV9kYXRhX3BvaW50cywgIlxuIikKYGBgCgojIyMgRGVzY3JpcHRpdmUgQW5hbHlzaXMKIyMjIyBUaW1lIFNlcmllcyBQbG90CmBgYHtyfQojIFBsb3QgdGhlIG9yaWdpbmFsIGRhdGEKZ2dwbG90KGRhdGEgPSByZXRhaWxfc2FsZXNfZGF0YSwgYWVzKHggPSBEQVRFLCB5ID0gUlNYRlNOKSkgKwogIGdlb21fbGluZShjb2xvciA9ICJibHVlIikgKwogIGxhYnModGl0bGUgPSAiVGltZSBTZXJpZXMgb2YgTW9udGhseSBSZXRhaWwgU2FsZXMiLAogICAgICAgeCA9ICJEYXRlIiwKICAgICAgIHkgPSAiUmV0YWlsIFNhbGVzIikgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCgpUaGUgdGltZSBzZXJpZXMgZGlzcGxheXMgYSBub3RpY2VhYmxlIHVwd2FyZCB0cmVuZCBpbiByZXRhaWxzIHNhbGVzIHdpdGggcGVyaW9kaWMgc3Bpa2VzIGluIHRoZSBmaW5hbCBtb250aHMgb2YgdGhlIHllYXIsIGluZGljYXRpbmcgdGhlIHByZXNlbmNlIG9mIHNlYXNvbmFsaXR5LgoKCiMjIyMgQm94IFBsb3QKYGBge3J9CiMgQ3JlYXRlIGEgdGltZSBzZXJpZXMgb2JqZWN0CnRzX2RhdGEgPC0gdHMocmV0YWlsX3NhbGVzX2RhdGEkUlNYRlNOLCBzdGFydCA9IGMoMjAxNCwgMTIpLCBmcmVxdWVuY3kgPSAxMikKCmJveHBsb3QodHNfZGF0YSB+IGN5Y2xlKHRzX2RhdGEpLCBtYWluPSJTZWFzb25hbCBCb3hwbG90IG9mIE1vbnRobHkgUmV0YWlsIFNhbGVzIiwgeWxhYiA9ICJTYWxlcyIsIHhsYWIgPSAiTW9udGgiKQpgYGAKCgpBbHRob3VnaCBpdCBtYWtlcyBzZW5zZSB0aGF0IHRoZSBtb250aCBvZiBOb3ZlbWJlciB3b3VsZCBzZWUgcGVhayBzYWxlcyBkdWUgdG8gQmxhY2sgRnJpZGF5IGFuZCBDeWJlciBNb25kYXkgZXZlbnRzLCBpdCBzZWVtcyBjb3VudGVyLWludHVpdGl2ZSB0aGF0IERlY2VtYmVyIHdvdWxkIGhhdmUgc3VjaCBhIHN0YXJrIGRlY3JlYXNlIGluIHNhbGVzLCBjb25zaWRlcmluZyB0aGUgaG9saWRheSBzZWFzb24uCgojIyMgQUNGIGFuZCBQQUNGIG9mIE9yaWdpbmFsIERhdGEKYGBge3J9CiMgQ3JlYXRlIEFDRiBwbG90CmFjZihyZXRhaWxfc2FsZXNfZGF0YSRSU1hGU04sIG1haW4gPSAiQUNGIG9mIE1vbnRobHkgUmV0YWlsIFNhbGVzIiwgbGFnLm1heCA9IDEwMCkKCiMgQ3JlYXRlIFBBQ0YgcGxvdApwYXIobWFyPWMoNSwgNSwgNCwgMikgKyAwLjEpCnBhY2YocmV0YWlsX3NhbGVzX2RhdGEkUlNYRlNOLCBtYWluID0gIlBBQ0Ygb2YgTW9udGhseSBSZXRhaWwgU2FsZXMiLCBsYWcubWF4ID0gMTAwKQpgYGAKIyMjIEFERiBUZXN0CmBgYHtyfQphZGZfdGVzdF9yZXN1bHQgPC0gYWRmLnRlc3QocmV0YWlsX3NhbGVzX2RhdGEkUlNYRlNOKQpwcmludChhZGZfdGVzdF9yZXN1bHQpCmBgYAoKClRoZSBkYXRhIHNob3dzIGNsZWFyIG5vbi1zdGF0aW9uYXJpdHkuIFRoZXJlZm9yZSwgd2UgcHJvY2VlZCB3aXRoIGRpZmZlcmVuY2luZyBtZWFzdXJlcyB0byBhY2hpZXZlIHN0YXRpb25hcml0eS4KCiMjIyBPYnRhaW5pbmcgU3RhdGlvbmFyeSBUaW1lIFNlcmllcwojIyMjIE9uZSBvcmRlciBvZiBkaWZmZXJlbmNpbmcKYGBge3J9CiMgQ2FsY3VsYXRlIHRoZSBkaWZmZXJlbmNlcyBvZiB0aGUgUlNYRlNOIHNlcmllcwpkaWZmX3NlcmllcyA8LSBkaWZmKHJldGFpbF9zYWxlc19kYXRhJFJTWEZTTikKCiMgUGxvdCB0aGUgZGlmZmVyZW5jZWQgZGF0YQpkaWZmX2RhdGEgPC0gZGF0YS5mcmFtZShEQVRFID0gcmV0YWlsX3NhbGVzX2RhdGEkREFURVstMV0sIERpZmZlcmVuY2UgPSBkaWZmX3NlcmllcykKCmdncGxvdChkYXRhID0gZGlmZl9kYXRhLCBhZXMoeCA9IERBVEUsIHkgPSBEaWZmZXJlbmNlKSkgKwogIGdlb21fbGluZShjb2xvciA9ICJyZWQiKSArCiAgbGFicyh0aXRsZSA9ICJEaWZmZXJlbmNlZCBUaW1lIFNlcmllcyBvZiBNb250aGx5IFJldGFpbCBTYWxlcyIsCiAgICAgICB4ID0gIkRhdGUiLAogICAgICAgeSA9ICJEaWZmZXJlbmNlIGluIFJldGFpbCBTYWxlcyIpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgpgYGB7cn0KYWRmX3Rlc3RfcmVzdWx0IDwtIGFkZi50ZXN0KGRpZmZfc2VyaWVzKQpwcmludChhZGZfdGVzdF9yZXN1bHQpCmBgYApwLXZhbHVlIGZyb20gQURGID0gMC4wMSA8IDAuMDUgLT4gc3RhdGlvbmFyeQoKIyMjIyBMb2cgdHJhbnNmb3JtYXRpb24gYW5kIG9uZSBvcmRlciBvZiBkaWZmZXJlbmNpbmcKYGBge3J9CiMgVGFrZSBsb2cgdHJhbnNmb3JtYXRpb24gb2YgZGF0YQpsb2dfc2VyaWVzIDwtIGxvZyhyZXRhaWxfc2FsZXNfZGF0YSRSU1hGU04pCgojIEFwcGx5IGRpZmZlcmVuY2luZwpkaWZmX2xvZ19zZXJpZXMgPC0gZGlmZihsb2dfc2VyaWVzKQoKIyBQbG90IHRoZSBkaWZmZXJlbmNlZCBkYXRhCmRpZmZfbG9nX2RhdGEgPC0gZGF0YS5mcmFtZShEQVRFID0gcmV0YWlsX3NhbGVzX2RhdGEkREFURVstMV0sIERpZmZlcmVuY2UgPSBkaWZmX2xvZ19zZXJpZXMpCgpnZ3Bsb3QoZGF0YSA9IGRpZmZfZGF0YSwgYWVzKHggPSBEQVRFLCB5ID0gRGlmZmVyZW5jZSkpICsKICBnZW9tX2xpbmUoY29sb3IgPSAicmVkIikgKwogIGxhYnModGl0bGUgPSAiRGlmZmVyZW5jZWQgVGltZSBTZXJpZXMgb2YgTW9udGhseSBSZXRhaWwgU2FsZXMiLAogICAgICAgeCA9ICJEYXRlIiwKICAgICAgIHkgPSAiRGlmZmVyZW5jZSBpbiBSZXRhaWwgU2FsZXMiKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKCmBgYHtyfQphZGZfdGVzdF9yZXN1bHQgPC0gYWRmLnRlc3QoZGlmZl9sb2dfc2VyaWVzKQpwcmludChhZGZfdGVzdF9yZXN1bHQpCmBgYAoKT25lIG9yZGVyIG9mIGRpZmZlcmVuY2luZywgYm90aCB3aXRoIGFuZCB3aXRob3V0IHRha2luZyB0aGUgbG9nYXJpdGhtaWMgdHJhbnNmb3JtYXRpb24sIGFjaGlldmVzIHN0YXRpb25hcml0eS4KCgojIyMgT25lIG9yZGVyIHNlYXNvbmFsIGRpZmZlcmVuY2luZwpgYGB7cn0KIyBBcHBseSBzZWFzb25hbCBkaWZmZXJlbmNpbmcgdG8gdGhlIFJTWEZTTiBzZXJpZXMKc2Vhc29uYWxfZGlmZl9zZXJpZXMgPC0gZGlmZihyZXRhaWxfc2FsZXNfZGF0YSRSU1hGU04sIGxhZyA9IDEyKQoKIyBDcmVhdGUgYSBkYXRhIGZyYW1lIGZvciB0aGUgc2Vhc29uYWxseSBkaWZmZXJlbmNlZCBkYXRhCnNlYXNvbmFsX2RpZmZfZGF0YSA8LSBkYXRhLmZyYW1lKERBVEUgPSByZXRhaWxfc2FsZXNfZGF0YSREQVRFWy0oMToxMildLCBEaWZmZXJlbmNlID0gc2Vhc29uYWxfZGlmZl9zZXJpZXMpCgojIFBsb3QgdGhlIHNlYXNvbmFsbHkgZGlmZmVyZW5jZWQgZGF0YQpnZ3Bsb3QoZGF0YSA9IHNlYXNvbmFsX2RpZmZfZGF0YSwgYWVzKHggPSBEQVRFLCB5ID0gRGlmZmVyZW5jZSkpICsKICBnZW9tX2xpbmUoY29sb3IgPSAiZ3JlZW4iKSArCiAgbGFicyh0aXRsZSA9ICJTZWFzb25hbGx5IERpZmZlcmVuY2VkIFRpbWUgU2VyaWVzIG9mIE1vbnRobHkgUmV0YWlsIFNhbGVzIiwKICAgICAgIHggPSAiRGF0ZSIsCiAgICAgICB5ID0gIlNlYXNvbmFsIERpZmZlcmVuY2UgaW4gUmV0YWlsIFNhbGVzIikgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCgojIyMjIFNlYXNvbmFsIGRpZmZlcmVuY2luZyBwbHV0IGFkZGl0aW9uYWwgZmlyc3QgZGlmZmVyZW5jaW5nIG9uIHNlYXNvbmFsbHkgZGlmZmVyZW5jZWQgZGF0YQpgYGB7cn0KIyBBcHBseSBzZWFzb25hbCBkaWZmZXJlbmNpbmcgdG8gdGhlIFJTWEZTTiBzZXJpZXMKc2Vhc29uYWxfZGlmZl9zZXJpZXMgPC0gZGlmZihyZXRhaWxfc2FsZXNfZGF0YSRSU1hGU04sIGxhZyA9IDEyKQoKIyBQZXJmb3JtIGFkZGl0aW9uYWwgZmlyc3QgZGlmZmVyZW5jaW5nIG9uIHNlYXNvbmFsbHkgZGlmZmVyZW5jZWQgZGF0YSB0byBlbnN1cmUgc3RhdGlvbmFyaXR5CmNvbWJpbmVkX2RpZmZfZGF0YSA8LSBkaWZmKHNlYXNvbmFsX2RpZmZfc2VyaWVzKQoKIyBDcmVhdGUgYSBkYXRhIGZyYW1lIGZvciB0aGUgc2Vhc29uYWxseSBkaWZmZXJlbmNlZCBkYXRhCmRvdWJseV9kaWZmX2RhdGEgPC0gZGF0YS5mcmFtZShEQVRFID0gcmV0YWlsX3NhbGVzX2RhdGEkREFURVstKDE6MTMpXSwgRGlmZmVyZW5jZSA9IGNvbWJpbmVkX2RpZmZfZGF0YSkKCiMgUGxvdCB0aGUgc2Vhc29uYWxseSBkaWZmZXJlbmNlZCBkYXRhCmdncGxvdChkYXRhID0gZG91Ymx5X2RpZmZfZGF0YSwgYWVzKHggPSBEQVRFLCB5ID0gRGlmZmVyZW5jZSkpICsKICBnZW9tX2xpbmUoY29sb3IgPSAicHVycGxlIikgKwogIGxhYnModGl0bGUgPSAiQ29tYmluZWQgU2Vhc29uYWxseSBEaWZmZXJlbmNlZCBUaW1lIFNlcmllcyBvZiBNb250aGx5IFJldGFpbCBTYWxlcyIsCiAgICAgICB4ID0gIkRhdGUiLAogICAgICAgeSA9ICJTZWFzb25hbCBEaWZmZXJlbmNlIGluIFJldGFpbCBTYWxlcyIpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgpgYGB7cn0KYWRmX3Rlc3RfcmVzdWx0IDwtIGFkZi50ZXN0KGNvbWJpbmVkX2RpZmZfZGF0YSkKcHJpbnQoYWRmX3Rlc3RfcmVzdWx0KQpgYGAKVGFraW5nIGEgc2Vhc29uYWwgZGlmZmVyZW5jZSBvZiB0aGUgZGF0YSwgYW5kIHRoZW4gYW4gYWRkaXRpb25hbCBvcmRlciBvZiBkaWZmZXJlbmNpbmcgcHJvZHVjZXMgdGhlIHRpbWUgc2VyaWVzIG1vc3QgcmVzZW1ibGluZyB3aGl0ZSBub2lzZSwgYWxiZWl0IHdpdGggY2xlYXIgdm9sYXRpbGl0eSBiZXR3ZWVuIDIwMjAgYW5kIDIwMjIuIFRoaXMgY2FuIHBlcmhhcHMgYmUgZXhwbGFpbmVkIGJ5IHRoZSBDT1ZJRC0xOSBwYW5kZW1pYywgd2hpY2ggc2F3IG1hbnkgc3RvcmUgY2xvc3VyZXMgYW5kIGFuZCBjZWFzaW5nIG9mIHJldGFpbCBhY3Rpdml0aWVzLiBXZSBub3cgaW52ZXN0aWdhdGUgdGhlIEFDRiBhbmQgUEFDRiBwbG90cyB3aXRoIHRoaXMgZGF0YS4KCgojIyMjIEFDRiBhbmQgUEFDRgpgYGB7cn0KIyBQbG90IEFDRiBmb3IgdGhlIGRpZmZlcmVuY2VkIGRhdGEKYWNmKGNvbWJpbmVkX2RpZmZfZGF0YSwgbWFpbj0iQUNGIG9mIERpZmZlcmVuY2VkIFJTWEZTTiIsIGxhZy5tYXg9NTApCgojIFBBQ0YgcGxvdCBmb3IgZGlmZmVyZW5jZWQgZGF0YQpwYXIobWFyPWMoNSwgNSwgNCwgMikgKyAwLjEpCnBhY2YoY29tYmluZWRfZGlmZl9kYXRhLCBtYWluPSJQQUNGIG9mIERpZmZlcmVuY2VkIFJTWEZTTiIsIGxhZy5tYXg9NTApCmBgYApUaGUgQUNGIGRpc3BsYXlzIGFuIGFicnVwdCBjdXQtb2ZmIGFmdGVyIGxhZyAxMiwgYW5kIHRoZSBQQUNGIGdyYWR1YWxseSBkZWNheXMsIHdoaWNoIGlzIGluZGljYXRpdmUgb2YgYSBNb3ZpbmcgQXZlcmFnZSBtb2RlbC4gCgoKIyMjIEZpdHRpbmcgYSBTQVJJTUEgTW9kZWwKYGBge3J9CiMgRml0IGEgc2Vhc29uYWwgQVJJTUEgbW9kZWwgbWFudWFsbHkKIyBOb24tc2Vhc29uYWwgcGFydDogQVJJTUEoMCwwLDIpLCBTZWFzb25hbCBwYXJ0OiBBUklNQSgwLDIsMTIpWzEyXQphZGp1c3RlZF9hcmltYV9tb2RlbCA8LSBBcmltYShjb21iaW5lZF9kaWZmX2RhdGEsIG9yZGVyID0gYygwLCAwLCAyKSwgc2Vhc29uYWwgPSBjKDAsIDAsIDEyKSkKCiMgU3VtbWFyeSBvZiB0aGUgYWRqdXN0ZWQgQVJJTUEgbW9kZWwKc3VtbWFyeShhZGp1c3RlZF9hcmltYV9tb2RlbCkKCiMgRGlhZ25vc3RpYyBjaGVja2luZyBvZiB0aGUgYWRqdXN0ZWQgbW9kZWwKY2hlY2tyZXNpZHVhbHMoYWRqdXN0ZWRfYXJpbWFfbW9kZWwpCgojIFVzZSB0c2RpYWcgdG8gZ2VuZXJhdGUgZGlhZ25vc3RpYyBwbG90cwp0c2RpYWcoYWRqdXN0ZWRfYXJpbWFfbW9kZWwpCmBgYAoKYGBge3J9CiMgRml0IGEgc2Vhc29uYWwgQVJJTUEgbW9kZWwKIyBOb24tc2Vhc29uYWwgcGFydDogQVJJTUEoMiwxLDApLCBTZWFzb25hbCBwYXJ0OiBBUklNQSgxLDEsMSlbMTJdCmFkanVzdGVkX2FyaW1hX21vZGVsXzIgPC0gQXJpbWEoY29tYmluZWRfZGlmZl9kYXRhLCBvcmRlciA9IGMoMCwgMCwgMTIpLCBzZWFzb25hbCA9IGMoMCwgMCwgMTApKQoKIyBTdW1tYXJ5IG9mIHRoZSBhZGp1c3RlZCBBUklNQSBtb2RlbApzdW1tYXJ5KGFkanVzdGVkX2FyaW1hX21vZGVsXzIpCgojIERpYWdub3N0aWMgY2hlY2tpbmcgb2YgdGhlIGFkanVzdGVkIG1vZGVsCmNoZWNrcmVzaWR1YWxzKGFkanVzdGVkX2FyaW1hX21vZGVsXzIpCgojIFVzZSB0c2RpYWcgdG8gZ2VuZXJhdGUgZGlhZ25vc3RpYyBwbG90cwp0c2RpYWcoYWRqdXN0ZWRfYXJpbWFfbW9kZWxfMikKYGBgClRoZSByZXNpZHVhbHMnIEFDRiBhbmQgUEFDRiBwbG90cyBpbmRpY2F0ZSB0aGF0IHRoZSBtb2RlbCdzIHJlc2lkdWFscyBhcmUgbW9zdGx5IHVuY29ycmVsYXRlZCwgc3VnZ2VzdGluZyBhIGdvb2QgZml0LCB0aG91Z2ggdGhlIFNBUklNQSgwLDAsMTIpKDAsMCwxMCkgaXMgc2xpZ2h0bHkgYmV0dGVyIHdpdGggYW4gQUlDIG9mIDI1MjEuODEgdmVyc3VzIDI1NDUuMjYuIFdoaWxlIHRoZSBTQVJJTUEgbW9kZWwgY2FwdHVyZXMgdGhlIHNlYXNvbmFsaXR5IGFuZCBnZW5lcmFsIHRyZW5kLCBpdCBtYXkgbm90IGZ1bGx5IGFjY291bnQgZm9yIHRoZSBleHRyZW1lIGZsdWN0dWF0aW9ucyBzZWVuIGluIHRoZSBoaXN0b3JpY2FsIGRhdGEuIEZvciBiZXR0ZXIgcHJlZGljdGlvbnMsIGl0IG1pZ2h0IGJlIG5lY2Vzc2FyeSB0byBleHBsb3JlIG90aGVyIG1vZGVscyBvciBpbmNsdWRlIGFkZGl0aW9uYWwgZXhwbGFuYXRvcnkgdmFyaWFibGVzLgoKCiMjIyBJbnZlc3RpZ2F0aW5nIEdBUkNIIE1vZGVsCgojIyMjIEludmVzdGlnYXRpbmcgU3F1YXJlZCBSZXNpZHVhbHMgdG8gSnVzdGlmeSBHQVJDSCBNb2RlbApgYGB7cn0KIyBDYWxjdWxhdGUgcmV0dXJucwpyZXR1cm5zIDwtIGRpZmYobG9nKHJldGFpbF9zYWxlc19kYXRhJFJTWEZTTikpCgojIFNxdWFyZSB0aGUgcmV0dXJucwpzcXVhcmVkX3JldHVybnMgPC0gcmV0dXJuc14yCgojIENyZWF0ZSBhIGRhdGEgZnJhbWUgZm9yIHBsb3R0aW5nCnNxdWFyZWRfcmV0dXJuc19kYXRhIDwtIGRhdGEuZnJhbWUoREFURSA9IHJldGFpbF9zYWxlc19kYXRhJERBVEVbLTFdLCBTcXVhcmVkX1JldHVybnMgPSBzcXVhcmVkX3JldHVybnMpCgojIFBsb3QgdGhlIHNxdWFyZWQgcmV0dXJucwpsaWJyYXJ5KGdncGxvdDIpCmdncGxvdChkYXRhID0gc3F1YXJlZF9yZXR1cm5zX2RhdGEsIGFlcyh4ID0gREFURSwgeSA9IFNxdWFyZWRfUmV0dXJucykpICsKICBnZW9tX2xpbmUoY29sb3IgPSAiYmx1ZSIpICsKICBsYWJzKHRpdGxlID0gIlNxdWFyZWQgUmV0dXJucyBvZiBNb250aGx5IFJldGFpbCBTYWxlcyIsCiAgICAgICB4ID0gIkRhdGUiLAogICAgICAgeSA9ICJTcXVhcmVkIFJldHVybnMiKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYApUaGUgc3F1YXJlZCByZXR1cm5zIG9mIHRoZSBtb250aGx5IHNhbGVzIGRhdGEgc2hvd3MgbXVjaCBwZXJpb2RpYyB2b2xhdGlsaXR5LCB3aGljaCBpbmRpY2F0ZXMgdGhhdCB0aGUgZGF0YSBpcyBhIHN0cm9uZyBjYW5kaWRhdGUgZm9yIHRoZSBHQVJDSCBtb2RlbC4KCiMjIyMgQUNGIGFuZCBQQUNGIG9mIFNxdWFyZWQgUmVzaWR1YWxzCmBgYHtyfQojIENhbGN1bGF0ZSByZXNpZHVhbHMKYXJpbWFfcmVzaWR1YWxzIDwtIHJlc2lkdWFscyhhZGp1c3RlZF9hcmltYV9tb2RlbF8yKQoKIyBTcXVhcmUgdGhlIHJlc2lkdWFscyB0byBmb2N1cyBvbiB2b2xhdGlsaXR5CnNxdWFyZWRfYXJpbWFfcmVzaWR1YWxzIDwtIGFyaW1hX3Jlc2lkdWFsc14yCgpwYXIobWFyPWMoNSwgNSwgNCwgMikgKyAwLjEpCiMgUGxvdCBBQ0Ygb2Ygc3F1YXJlZCByZXNpZHVhbHMKQWNmKHNxdWFyZWRfYXJpbWFfcmVzaWR1YWxzLCBtYWluPSJBQ0Ygb2YgU3F1YXJlZCBSZXNpZHVhbHMiKQoKIyBQbG90IFBBQ0Ygb2Ygc3F1YXJlZCByZXNpZHVhbHMKUGFjZihzcXVhcmVkX2FyaW1hX3Jlc2lkdWFscywgbWFpbj0iUEFDRiBvZiBTcXVhcmVkIFJlc2lkdWFscyIpCmBgYApUaGUgQUNGIG9mIHRoZSBzcXVhcmVkIHJlc2lkdWFscyBzaG93cyBzaWduaWZpY2FudCBhdXRvY29ycmVsYXRpb24gYXQgdmFyaW91cyBsYWdzLCBzdWdnZXN0aW5nIHBlcmlvZHMgb2YgaGlnaCB2b2xhdGlsaXR5IGZvbGxvd2VkIGJ5IGhpZ2ggdm9sYXRpbGl0eSBhbmQgcGVyaW9kcyBvZiBsb3cgdm9sYXRpbGl0eSBmb2xsb3cgcGVyaW9kcyBvZiBsb3cgdm9sYXRpbGl0eS4gVGhpcyBwYXR0ZXJuIGlzIGluZGljYXRpdmUgb2Ygdm9sYXRpbGl0eSBjbHVzdGVyaW5nLCBhIGNoYXJhY3RlcmlzdGljIG9mIGZpbmFuY2lhbCB0aW1lIHNlcmllcyBkYXRhLiBUaGUgcHJlc2VuY2Ugb2Ygc2lnbmlmaWNhbnQgYXV0b2NvcnJlbGF0aW9uIGluIHNxdWFyZWQgcmVzaWR1YWxzIGFsc28gc3VnZ2VzdHMgbm9ubGluZWFyaXR5IGluIHZhcmlhbmNlLCBoaWdobGlnaHRpbmcgYSBuZWVkIGZvciBtb2RlbHMgbGlrZSBHQVJDSC4KCgojIyMjIEZpdHRpbmcgdGhlIEdBUkNIIE1vZGVsIHRvIHNlYXNvbmFsbHkgZGlmZmVyZW5jZWQgZGF0YSBwbHVzIGFuIGFkZGl0aW9uYWwgb3JkZXIgb2YgZGlmZmVyZW5jaW5nCmBgYHtyfQpjb21iaW5lZF94dHMgPC0geHRzKGNvbWJpbmVkX2RpZmZfZGF0YSwgb3JkZXIuYnkgPSBhcy5EYXRlKHRpbWUoY29tYmluZWRfZGlmZl9kYXRhKSkpCgojIEZpdCB0aGUgU0FSSU1BIG1vZGVsCiMgRXh0cmFjdCByZXNpZHVhbHMgZnJvbSB0aGUgU0FSSU1BIG1vZGVsCnNhcmltYV9yZXNpZHVhbHMgPC0gcmVzaWR1YWxzKGFkanVzdGVkX2FyaW1hX21vZGVsXzIpCgojIEV4dHJhY3QgZGF0ZXMgZnJvbSB0aGUgY29tYmluZWRfeHRzCmRhdGVzIDwtIGluZGV4KGNvbWJpbmVkX3h0cykKCiMgQ29udmVydCBTQVJJTUEgcmVzaWR1YWxzIHRvIHh0cyBmb3JtYXQKc2FyaW1hX3Jlc2lkdWFsc194dHMgPC0geHRzKHNhcmltYV9yZXNpZHVhbHMsIG9yZGVyLmJ5ID0gZGF0ZXMpCgojIEZpdCBhIEdBUkNIIG1vZGVsIG9uIHRoZSBTQVJJTUEgcmVzaWR1YWxzCiMgRGVmaW5lIGEgc2ltcGxlIEdBUkNIKDEsMSkgbW9kZWwKZ2FyY2hfc3BlYyA8LSB1Z2FyY2hzcGVjKAogIHZhcmlhbmNlLm1vZGVsID0gbGlzdChtb2RlbCA9ICJzR0FSQ0giLCBnYXJjaE9yZGVyID0gYygxLCAxKSksCiAgbWVhbi5tb2RlbCA9IGxpc3QoYXJtYU9yZGVyID0gYygwLCAwKSwgaW5jbHVkZS5tZWFuID0gRkFMU0UpLAogIGRpc3RyaWJ1dGlvbi5tb2RlbCA9ICJub3JtIgopCgojIEZpdCB0aGUgR0FSQ0ggbW9kZWwgb24gU0FSSU1BIHJlc2lkdWFscwpnYXJjaF9maXQgPC0gdWdhcmNoZml0KHNwZWMgPSBnYXJjaF9zcGVjLCBkYXRhID0gc2FyaW1hX3Jlc2lkdWFsc194dHMpCgojIFN1bW1hcml6ZSBHQVJDSCBtb2RlbCBmaXQKc3VtbWFyeShnYXJjaF9maXQpCgojIEV2YWx1YXRlIHRoZSBDb21iaW5lZCBNb2RlbAojIENoZWNrIHJlc2lkdWFscyBvZiB0aGUgU0FSSU1BIG1vZGVsCmNoZWNrcmVzaWR1YWxzKGFkanVzdGVkX2FyaW1hX21vZGVsXzIpCgojIFBsb3QgZGlhZ25vc3RpYyBwbG90cyBmb3IgR0FSQ0ggbW9kZWwKcGxvdChnYXJjaF9maXQpCgojIENoZWNrIEFDRiBvZiBzdGFuZGFyZGl6ZWQgcmVzaWR1YWxzIGZyb20gdGhlIEdBUkNIIG1vZGVsCmdhcmNoX3Jlc2lkdWFscyA8LSByZXNpZHVhbHMoZ2FyY2hfZml0LCBzdGFuZGFyZGl6ZSA9IFRSVUUpCgojIENvbnZlcnQgR0FSQ0ggcmVzaWR1YWxzIHRvIHh0cyBmb3JtYXQsIGFkanVzdCBmb3IgYW55IGRpZmZlcmVuY2luZwpnYXJjaF9yZXNpZHVhbHNfeHRzIDwtIHh0cyhnYXJjaF9yZXNpZHVhbHMsIG9yZGVyLmJ5ID0gZGF0ZXNbMTpsZW5ndGgoZ2FyY2hfcmVzaWR1YWxzKV0pICAjIEFkanVzdCBpbmRleCBpZiBuZWNlc3NhcnkKCiMgUGxvdCBBQ0YgdXNpbmcgUGVyZm9ybWFuY2VBbmFseXRpY3MKY2hhcnQuQUNGcGx1cyhnYXJjaF9yZXNpZHVhbHNfeHRzLCBtYWluID0gIkFDRiBvZiBTdGFuZGFyZGl6ZWQgR0FSQ0ggUmVzaWR1YWxzIikKCiMgUGxvdCByb2xsaW5nIHZvbGF0aWxpdHkgdG8gYXNzZXNzIGR5bmFtaWMgdm9sYXRpbGl0eSBvdmVyIHRpbWUKY2hhcnQuUm9sbGluZ1BlcmZvcm1hbmNlKGdhcmNoX3Jlc2lkdWFsc194dHMsIHdpZHRoID0gMTIsIEZVTiA9ICJzZCIsIG1haW4gPSAiUm9sbGluZyBWb2xhdGlsaXR5IChTdGFuZGFyZCBEZXZpYXRpb24pIikKYGBgClRoZSBBQ0YgYW5kIFBBQ0Ygb2YgdGhlIFN0YW5kYXJkaXplZCBSZXNpZHVhbHMgc2hvdyBubyBzaWduaWZpY2FudCBzcGlrZXMgZXhjZXB0IGZvciB0aGUgZmlyc3QsIGluZGljYXRpbmcgdGhhdCB0aGUgcmVzaWR1YWxzIGFyZSB1bmNvcnJlbGF0ZWQgYW5kIHJlc2VtYmxlIHdoaXRlIG5vaXNlLiBJbiB0aGUgUVEgcGxvdCwgdGhlIHBvaW50cyBmYWxsIGNsb3NlIHRvIHRoZSA0NS1kZWdyZWUgbGluZSBhbG9uZyB0aGUgY2VudGVyIGFuZCB0b3AtcmlnaHQtbW9zdCBwb3J0aW9uIG9mIHRoZSBncmFwaCwgYWxiZWl0IHdpdGggc2lnbmlmaWNhbnQgZGV2aWF0aW9ucyBhdCB0aGUgYm90dG9tIHRhaWwuCgoKYGBge3J9CiMgU2V0IHRoZSBtYXhpbXVtIG51bWJlciBvZiBsYWdzIGZvciB0aGUgTGp1bmctQm94IHRlc3QKbWF4X2xhZ3MgPC0gMjAKCiMgSW5pdGlhbGl6ZSBhIHZlY3RvciB0byBzdG9yZSBwLXZhbHVlcwpwX3ZhbHVlcyA8LSBudW1lcmljKG1heF9sYWdzKQoKIyBDYWxjdWxhdGUgdGhlIExqdW5nLUJveCB0ZXN0IHAtdmFsdWVzIGZvciBlYWNoIGxhZwpmb3IgKGxhZyBpbiAxOm1heF9sYWdzKSB7CiAgbGJfdGVzdCA8LSBCb3gudGVzdChnYXJjaF9yZXNpZHVhbHMsIGxhZyA9IGxhZywgdHlwZSA9ICJManVuZy1Cb3giLCBmaXRkZiA9IDApCiAgcF92YWx1ZXNbbGFnXSA8LSBsYl90ZXN0JHAudmFsdWUKfQoKIyBDcmVhdGUgYSBwbG90IG9mIHAtdmFsdWVzCnBsb3QoMTptYXhfbGFncywgcF92YWx1ZXMsIHR5cGUgPSAiYiIsIHBjaCA9IDE5LCBjb2wgPSAiYmx1ZSIsCiAgICAgeGxhYiA9ICJMYWciLCB5bGFiID0gInAtdmFsdWUiLAogICAgIG1haW4gPSAiTGp1bmctQm94IFRlc3QgcC12YWx1ZXMgZm9yIFN0YW5kYXJkaXplZCBSZXNpZHVhbHMiKQphYmxpbmUoaCA9IDAuMDUsIGNvbCA9ICJyZWQiLCBsdHkgPSAyKSAgIyBBZGQgYSBsaW5lIGF0IHRoZSAwLjA1IHNpZ25pZmljYW5jZSBsZXZlbAoKIyBDcmVhdGluZyBhIGRhdGFmcmFtZSBmb3IgcGxvdHRpbmcKcmVzaWR1YWxzX2RmIDwtIGRhdGEuZnJhbWUoUmVzaWR1YWxzID0gYXMubnVtZXJpYyhnYXJjaF9yZXNpZHVhbHMpKQpgYGAKYGBge3J9CiMgU3BlY2lmeSB0aGUgbnVtYmVyIG9mIHBlcmlvZHMgeW91IHdhbnQgdG8gZm9yZWNhc3QKZm9yZWNhc3RfaG9yaXpvbiA8LSAxMgoKIyBGb3JlY2FzdCBmdXR1cmUgdmFsdWVzIHVzaW5nIHRoZSBTQVJJTUEgbW9kZWwKc2FyaW1hX2ZvcmVjYXN0IDwtIGZvcmVjYXN0KGFkanVzdGVkX2FyaW1hX21vZGVsXzIsIGggPSBmb3JlY2FzdF9ob3Jpem9uKQoKIyBQbG90IFNBUklNQSBmb3JlY2FzdApwbG90KHNhcmltYV9mb3JlY2FzdCwgbWFpbiA9ICJTQVJJTUEgRm9yZWNhc3QiKQoKIyBTdGVwIDQ6IEZvcmVjYXN0IHVzaW5nIHRoZSBHQVJDSCBtb2RlbApnYXJjaF9mb3JlY2FzdCA8LSB1Z2FyY2hmb3JlY2FzdChnYXJjaF9maXQsIG4uYWhlYWQgPSBmb3JlY2FzdF9ob3Jpem9uKQoKIyBFeHRyYWN0IGZvcmVjYXN0ZWQgdm9sYXRpbGl0eSAoc3RhbmRhcmQgZGV2aWF0aW9uKSBmcm9tIHRoZSBHQVJDSCBtb2RlbAp2b2xhdGlsaXR5X2ZvcmVjYXN0IDwtIHNpZ21hKGdhcmNoX2ZvcmVjYXN0KQoKIyBQcmludCB2b2xhdGlsaXR5IGZvcmVjYXN0CnByaW50KHZvbGF0aWxpdHlfZm9yZWNhc3QpCgojIENvbWJpbmUgU0FSSU1BIGZvcmVjYXN0IHdpdGggR0FSQ0ggdm9sYXRpbGl0eSBmb3JlY2FzdApwbG90KHNhcmltYV9mb3JlY2FzdCwgbWFpbiA9ICJGb3JlY2FzdGVkIE1lYW4gd2l0aCBTQVJJTUEiLCB4bGFiID0gIlRpbWUiLCB5bGFiID0gIlZhbHVlcyIpCmxpbmVzKHZvbGF0aWxpdHlfZm9yZWNhc3QsIGNvbCA9ICJyZWQiLCBsdHkgPSAyKQoKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIlNBUklNQSBNZWFuIiwgIkdBUkNIIFZvbGF0aWxpdHkiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMToyKQpgYGAKCgoKIyMgQUFQTCBNb250aGx5IERhdGEgMjAxNi0yMDI0CiMjIyBMb2FkICYgSW5zcGVjdCB0aGUgRGF0YQoKYGBge3J9CiMgTG9hZCB0aGUgZGF0YQphYXBsX21vbnRobHlfZGF0YSA8LSByZWFkLmNzdigifi9Eb2N1bWVudHMvR2l0SHViL01BLTY0MS1Db3Vyc2UtUHJvamVjdC9BQVBMX01vbnRobHkyMDE2LmNzdiIpCgojIENvbnZlcnQgdGhlIGRhdGUgY29sdW1uIHRvIERhdGUgdHlwZQphYXBsX21vbnRobHlfZGF0YSREYXRlIDwtIGFzLkRhdGUoYWFwbF9tb250aGx5X2RhdGEkRGF0ZSwgZm9ybWF0PSIlWS0lbS0lZCIpCgojIEluc3BlY3QgdGhlIGRhdGEKaGVhZChhYXBsX21vbnRobHlfZGF0YSkKc3VtbWFyeShhYXBsX21vbnRobHlfZGF0YSkKYGBgCgpBYm91dCB0aGUgRGF0YToKCi0gMTAxIGRhdGEgcG9pbnRzIHNwYW5uaW5nIGZyb20gMDEvMDEvMTYgdG8gMDUvMDEvMjQKLSBEYXRhIGluY2x1ZGVzIHRoZSBtb250aGx5IG9wZW4sIGhpZ2gsIGxvdywgY2xvc2UsIGFuZCBhZGp1c3RlZCBjbG9zZSBwcmljZXMgb2YgdGhlIGFwcGxlIHN0b2NrCgoKIyMjIENyZWF0ZSBhIFRpbWUgU2VyaWVzIE9iamVjdAoKYGBge3J9CiMgQ3JlYXRlIGEgdGltZSBzZXJpZXMgb2JqZWN0CmFhcGxtb250aGx5X3RzIDwtIHRzKGFhcGxfbW9udGhseV9kYXRhJENsb3NlLCBzdGFydD1jKDIwMTYsIDAxKSwgZW5kID0gYygyMDI0LCAwNSksIGZyZXF1ZW5jeT0xMikgCmBgYAoKCiMjIyBEZXNjcmlwdnRpdmUgQW5hbHlzaXMKCmBgYHtyfQojIERlc2NyaXB0aXZlIEFuYWx5c2lzCnBsb3QoYWFwbG1vbnRobHlfdHMsIG1haW49Ik1vbnRobHkgQXBwbGUgU3RvY2sgUHJpY2VzIiwgeWxhYj0iQ2xvc2UgUHJpY2UiLCB4bGFiPSJUaW1lIikKc3VtbWFyeShhYXBsbW9udGhseV90cykKYm94cGxvdChhYXBsbW9udGhseV90cyB+IGN5Y2xlKGFhcGxtb250aGx5X3RzKSwgbWFpbj0iU2Vhc29uYWwgQm94cGxvdCBvZiBNb250aGx5IEFwcGxlIFN0b2NrIFByaWNlcyIsIHlsYWI9IkNsb3NlIFByaWNlIikKYGBgCgoKVGltZSBTZXJpZXMgUGxvdDoKCi0gVGhlcmUgaXMgYSBjbGVhciB1cHdhcmQgdHJlbmQgaW4gQXBwbGUgc3RvY2sgcHJpY2VzIG92ZXIgdGhlIHBlcmlvZC4gVGhlIHByaWNlcyBzaG93IGEgc3Vic3RhbnRpYWwgaW5jcmVhc2UsIHBhcnRpY3VsYXJseSBzdGFydGluZyBhcm91bmQgMjAxOS4KLSBUaGVyZSBpcyB2aXNpYmxlIHZvbGF0aWxpdHkgaW4gdGhlIHN0b2NrIHByaWNlcywgd2l0aCBmbHVjdHVhdGlvbnMgYmVjb21pbmcgbW9yZSBwcm9ub3VuY2VkIGluIHRoZSBsYXRlciB5ZWFycy4KLSBUaGUgaW5jcmVhc2VkIHZvbGF0aWxpdHkgbWF5IGltcGx5IGhpZ2hlciByaXNrIGZvciBpbnZlc3RvcnMsIGFzIHRoZSBzdG9jayBwcmljZXMgaGF2ZSBsYXJnZXIgc3dpbmdzLgoKU3VtbWFyeToKCi0gVGhlIG1lYW4gYW5kIG1lZGlhbiB2YWx1ZXMgc3VnZ2VzdCB0aGF0IHRoZSBjZW50cmFsIHRlbmRlbmN5IG9mIHRoZSBzdG9jayBwcmljZXMgaXMgYXJvdW5kIDczIHRvIDk2LgotIFRoZSByYW5nZSBpbmRpY2F0ZXMgdGhhdCB0aGUgc3RvY2sgcHJpY2UgaGFzIHZhcmllZCBzaWduaWZpY2FudGx5IG92ZXIgdGhlIHBlcmlvZC4KClNlYXNvbmFsIEJveHBsb3Q6CgotIFRoZSBwcmVzZW5jZSBvZiBzZWFzb25hbGl0eSBzdWdnZXN0cyB0aGF0IGNlcnRhaW4gbW9udGhzIHRlbmQgdG8gaGF2ZSBoaWdoZXIgb3IgbG93ZXIgc3RvY2sgcHJpY2VzIGNvbnNpc3RlbnRseSwgd2hpY2ggY2FuIGJlIGNydWNpYWwgZm9yIHNlYXNvbmFsIHRyYWRpbmcgc3RyYXRlZ2llcy4KLSBUaGUgc2Vhc29uYWwgYm94cGxvdCByZXZlYWxzIG1pbm9yIG1vbnRobHkgcGF0dGVybnMgYW5kIHZhcmlhYmlsaXR5LCBzdWdnZXN0aW5nIHRoYXQgc2Vhc29uYWxpdHkgc2hvdWxkIGJlIGNvbnNpZGVyZWQgaW4gdHJhZGluZyBzdHJhdGVnaWVzIGFuZCByaXNrIAoKCiMjIyBBQ0YsIFBBQ0YsICYgRUFDRiBQbG90cwoKYGBge3J9CiMgQUNGIGFuZCBQQUNGIFBsb3RzCnBhcihtYXI9Yyg1LCA1LCA0LCAyKSArIDAuMSkKYWNmKGFhcGxtb250aGx5X3RzLCBtYWluPSJBQ0Ygb2YgTW9udGhseSBBcHBsZSBTdG9jayBQcmljZXMiLCBsYWcubWF4ID0gNzIpCnBhY2YoYWFwbG1vbnRobHlfdHMsIG1haW49IlBBQ0Ygb2YgTW9udGhseSBBcHBsZSBTdG9jayBQcmljZXMiLCBsYWcubWF4ID0gNzIpCmVhY2YoYWFwbG1vbnRobHlfdHMpCmBgYAoKCkFDRiBQbG90OgoKLSBUaGUgZ3JhZHVhbCBkZWNheSBpbiB0aGUgQUNGIGluZGljYXRlcyB0aGUgcHJlc2VuY2Ugb2YgYSB0cmVuZCBjb21wb25lbnQgaW4gdGhlIHRpbWUgc2VyaWVzLiBUaGUgc2VyaWVzIGlzIGxpa2VseSBub24tc3RhdGlvbmFyeS4KLSBTaWduaWZpY2FudCBhdXRvY29ycmVsYXRpb25zIHN1Z2dlc3QgdGhhdCB0aGUgZGF0YSBpcyBub3QgcmFuZG9tIGFuZCBwYXN0IHZhbHVlcyBjYW4gaGVscCBwcmVkaWN0IGZ1dHVyZSB2YWx1ZXMuCi0gQSBoaWdoIGRlZ3JlZSBvZiBwb3NpdGl2ZSBhdXRvY29ycmVsYXRpb24gYXQgdGhlIGZpcnN0IGZldyBsYWdzIGltcGxpZXMgbW9tZW50dW0gaW4gdGhlIHN0b2NrIHByaWNlcywgd2hpY2ggaXMgY29tbW9uIGluIGZpbmFuY2lhbCB0aW1lIHNlcmllcy4KCgpQQUNGIFBsb3Q6CgotIFRoZSBzaGFycCBkcm9wIGFmdGVyIHRoZSBmaXJzdCBsYWcgaW4gdGhlIFBBQ0Ygc3VnZ2VzdHMgdGhhdCBhbiBBUigxKSBtb2RlbCBtYXkgYmUgYXBwcm9wcmlhdGUgZm9yIGNhcHR1cmluZyB0aGUgcmVsYXRpb25zaGlwIGluIHRoZSBkYXRhLgotIFRoZSBzaWduaWZpY2FudCBmaXJzdCBsYWcgaW5kaWNhdGVzIHRoYXQgdGhlIGltbWVkaWF0ZSBwYXN0IHZhbHVlIGhhcyBhIHN0cm9uZyBpbmZsdWVuY2Ugb24gdGhlIGN1cnJlbnQgdmFsdWUsIHdoaWxlIHRoZSBpbmZsdWVuY2Ugb2YgdmFsdWVzIGZ1cnRoZXIgaW4gdGhlIHBhc3QgZGltaW5pc2hlcyBxdWlja2x5LgotIFRoaXMgcGF0dGVybiBzdXBwb3J0cyB0aGUgdXNlIG9mIGEgc2ltcGxlIGF1dG9yZWdyZXNzaXZlIG1vZGVsLCBhcyB0aGUgY29tcGxleGl0eSBiZXlvbmQgdGhlIGZpcnN0IGxhZyBkb2VzIG5vdCBhZGQgbXVjaCBleHBsYW5hdG9yeSBwb3dlci4KCgoKIyMjIEFERiBUZXN0CgpgYGB7cn0KIyBBdWdtZW50ZWQgRGlja2V5LUZ1bGxlciBUZXN0CmFkZl90ZXN0IDwtIGFkZi50ZXN0KGFhcGxtb250aGx5X3RzLCBhbHRlcm5hdGl2ZT0ic3RhdGlvbmFyeSIpCnByaW50KGFkZl90ZXN0KQpgYGAKCgotIFNpbmNlIHRoZSBwLXZhbHVlIGlzIGdyZWF0ZXIgdGhhbiAwLjA1LCB3ZSBmYWlsIHRvIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIHRoYXQgdGhlIHRpbWUgc2VyaWVzIGhhcyBhIHVuaXQgcm9vdC4gVGhpcyBpbmRpY2F0ZXMgdGhhdCB0aGUgc2VyaWVzIGlzIG5vbi1zdGF0aW9uYXJ5LgotIFRoZSBub24tc3RhdGlvbmFyaXR5IG9ic2VydmVkIGZyb20gdGhlIEFERiB0ZXN0IHJlc3VsdHMgaW1wbGllcyB0aGF0IGRpZmZlcmVuY2luZyB0aGUgdGltZSBzZXJpZXMgaXMgbmVjZXNzYXJ5IHRvIGFjaGlldmUgc3RhdGlvbmFyaXR5LgoKCmBgYHtyfQojIERpZmZlcmVuY2luZyB0aGUgc2VyaWVzIGlmIGl0IGlzIG5vdCBzdGF0aW9uYXJ5CmlmIChhZGZfdGVzdCRwLnZhbHVlID4gMC4wNSkgewogIHRzX2RhdGFfZGlmZiA8LSBkaWZmKGFhcGxtb250aGx5X3RzLCBkaWZmZXJlbmNlcz0xKQogIGFkZl90ZXN0X2RpZmYgPC0gYWRmLnRlc3QodHNfZGF0YV9kaWZmLCBhbHRlcm5hdGl2ZT0ic3RhdGlvbmFyeSIpCiAgcHJpbnQoYWRmX3Rlc3RfZGlmZikKICAKICAjIFVwZGF0ZSB0aGUgdGltZSBzZXJpZXMgZGF0YSB0byB0aGUgZGlmZmVyZW5jZWQgc2VyaWVzCiAgYWFwbG1vbnRobHlfdHMgPC0gdHNfZGF0YV9kaWZmCn0KYGBgCgoKLSBTaW5jZSB0aGUgcC12YWx1ZSBpcyBsZXNzIHRoYW4gMC4wNSwgd2UgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB0aGUgdGltZSBzZXJpZXMgaGFzIGEgdW5pdCByb290LiBUaGlzIGluZGljYXRlcyB0aGF0IHRoZSBkaWZmZXJlbmNlZCBzZXJpZXMgaXMgc3RhdGlvbmFyeS4KLSBXaXRoIHRoZSBkaWZmZXJlbmNlZCBzZXJpZXMgYmVpbmcgc3RhdGlvbmFyeSwgaXQgaXMgbm93IHN1aXRhYmxlIGZvciBmaXR0aW5nIEFSSU1BIG1vZGVscy4KIAoKYGBge3J9CiMgVGltZSBTZXJpZXMgUGxvdCBhZnRlciBEaWZmZXJlbmNpbmcKcGxvdChhYXBsbW9udGhseV90cywgbWFpbj0iTW9udGhseSBBcHBsZSBTdG9jayBQcmljZXMiLCB5bGFiPSJDbG9zZSBQcmljZSIsIHhsYWI9IlRpbWUiKQoKIyBBQ0YgYW5kIFBBQ0YgUGxvdHMKcGFyKG1hcj1jKDUsIDUsIDQsIDIpICsgMC4xKQphY2YoYWFwbG1vbnRobHlfdHMsIG1haW49IkFDRiBvZiBNb250aGx5IEFwcGxlIFN0b2NrIFByaWNlcyIsIGxhZy5tYXggPSA3MikKcGFjZihhYXBsbW9udGhseV90cywgbWFpbj0iUEFDRiBvZiBNb250aGx5IEFwcGxlIFN0b2NrIFByaWNlcyIsIGxhZy5tYXggPSA3MikKZWFjZihhYXBsbW9udGhseV90cykKYGBgCgoKLSBXZSBjYW4gc2VlIHRoYXQgYWZ0ZXIgZGlmZmVyZW5jaW5nIHRoZSB0aW1lLXNlcmllcyBhcHBlYXJzIHRvIGJlIHN0YXRpb25hcnkuCgpBQ0YgUGxvdDoKCi0gRXhwb25lbnRpYWwgZGVjYXksIHN1Z2dlc3RzIGFuIEFSIG1vZGVsLgotIFNwaWtlIGF0IGNlcnRhaW4gbGFncyBhbmQgdGhlbiBubyBzaWduaWZpY2FudCBhdXRvY29ycmVsYXRpb24gaW5kaWNhdGVzIGFuIE1BIG1vZGVsLgotIExhZyAxOiBTdHJvbmcgcG9zaXRpdmUgYXV0b2NvcnJlbGF0aW9uLCBwb3NzaWJseSBzdWdnZXN0aW5nIGFuIE1BKDEpIGNvbXBvbmVudC4KLSBGdXJ0aGVyIExhZ3M6IEdyYWR1YWwgZGVjYXkgc3VnZ2VzdHMgcG90ZW50aWFsIEFSIGNvbXBvbmVudCwgYnV0IGluaXRpYWwgc3Bpa2VzIG1heSBhbHNvIGluZGljYXRlIGFuIE1BIGNvbXBvbmVudC4KClBBQ0YgUGxvdDoKCi0gTGFnIDE6IEEgc2lnbmlmaWNhbnQgc3Bpa2UsIHN1Z2dlc3RpbmcgYW4gQVIoMSkgY29tcG9uZW50LgotIEZ1cnRoZXIgTGFnczogVGhlIGxhY2sgb2Ygc2lnbmlmaWNhbnQgc3Bpa2VzIGFmdGVyIHRoZSBpbml0aWFsIG9uZXMgaW1wbGllcyBubyBzdHJvbmcgYWRkaXRpb25hbCBBUiB0ZXJtcy4KCkVBQ0YgUGxvdDoKCi0gQVJJTUEoMSwwLDEpOiBEdWUgdG8gdGhlIHNpZ25pZmljYW50IHNwaWtlIGF0IGxhZyAxIGluIGJvdGggQUNGIGFuZCBQQUNGIHBsb3RzLgotIEFSSU1BKDAsMCwxKTogRHVlIHRvIHRoZSBpbml0aWFsIHNwaWtlcyBpbiB0aGUgQUNGIGFuZCBhIHF1aWNrbHkgZGVjYXlpbmcgUEFDRi4KLSBBUklNQSgxLDAsMCk6IER1ZSB0byB0aGUgQVIgY29tcG9uZW50IHN1Z2dlc3RlZCBieSBQQUNGLgotIEFSSU1BKDIsMCwxKSBvciBBUklNQSgxLDAsMik6ICBFQUNGIGluZGljYXRlcyBwb3RlbnRpYWwgY29tYmluZWQgQVIgYW5kIE1BIHRlcm1zLgoKCiMjIyBGaXQgQVIsIE1BLCBhbmQgQVJNQSBNb2RlbHMKIyMjIyBBUiBNb2RlbApgYGB7cn0KIyBGaXQgQVIgbW9kZWwKYXJfbW9kZWwgPC0gQXJpbWEoYWFwbG1vbnRobHlfdHMsIG9yZGVyPWMoMiwwLDApKQpzdW1tYXJ5KGFyX21vZGVsKQpgYGAKCgotIEFSKDEpIENvZWZmaWNpZW50PTAuMDQwOSwgaXMgYSBzbWFsbCBwb3NpdGl2ZSB2YWx1ZSBjbG9zZSB0byB6ZXJvIHdoaWNoIHN1Z2dlc3RzIGEgd2VhayBwb3NpdGl2ZSBjb3JyZWxhdGlvbiB3aXRoIHRoZSBpbW1lZGlhdGUgcGFzdCBtb250aCdzIHZhbHVlCi0gQVIoMikgQ29lZmZpY2llbnQ9LTAuMjcwOCwgaXMgYSBuZWdhdGl2ZSB2YWx1ZSB3aGljaCBzdWdnZXN0cyB0aGF0IHRoZSBwcmljZSB0d28gbW9udGhzIGFnbyBoYXMgYSBtb2RlcmF0ZSBpbnZlcnNlIHJlbGF0aW9uc2hpcCB3aXRoIHRoZSBjdXJyZW50IG1vbnRoJ3MgcHJpY2UKLSBNZWFuPTEuNjQ3NiwgdGhlIGF2ZXJhZ2UgbGV2ZWwgb2YgdGhlIHNlcmllcyBhZnRlciByZW1vdmluZyB0aGUgYXV0b3JlZ3Jlc3NpdmUgZWZmZWN0cwotIFRoZSBBUigxKSBjb2VmZmljaWVudCBpcyBzbWFsbCwgd2hpbGUgdGhlIEFSKDIpIGNvZWZmaWNpZW50IGlzIG1vZGVyYXRlIGFuZCBuZWdhdGl2ZSwgc3VnZ2VzdGluZyBzb21lIGNvbXBsZXhpdHkgaW4gaG93IHBhc3QgdmFsdWVzIHJlbGF0ZSB0byBjdXJyZW50IHZhbHVlcwotIFRoZSBtb2RlbCBhY2NvdW50cyBmb3IgdGhlIGluZmx1ZW5jZSBvZiB0d28gcHJldmlvdXMgbW9udGhzJyBwcmljZXMsIGNhcHR1cmluZyBib3RoIGltbWVkaWF0ZSBhbmQgZGVsYXllZCBlZmZlY3RzCi0gVGhlIHZhcmlhbmNlIGlzIHJlbGF0aXZlbHkgaGlnaCwgd2hpY2ggbWF5IGluZGljYXRlIHN1YnN0YW50aWFsIHVuZXhwbGFpbmVkIHZhcmlhYmlsaXR5Ci0gUk1TRSBhbmQgTUFFIGFyZSBtb2RlcmF0ZSwgaW5kaWNhdGluZyB0aGF0IHRoZSBtb2RlbCBoYXMgcmVhc29uYWJsZSBhY2N1cmFjeSBidXQgY291bGQgYmUgaW1wcm92ZWQKLSBIaWdoIE1QRSBhbmQgTUFQRSBzdWdnZXN0IHNvbWUgZm9yZWNhc3RzIG1pZ2h0IGJlIHNpZ25pZmljYW50bHkgb2ZmIGZyb20gYWN0dWFsIHZhbHVlcwoKCiMjIyMjIFJlc2lkdWFsIEFuYWx5c2lzCgpgYGB7cn0KIyBQZXJmb3JtIGRpYWdub3N0aWNzIGZvciBBUigyKQpwYXIobWFyPWMoNSwgNSwgNCwgMikgKyAwLjEpCnRzZGlhZyhhcl9tb2RlbCwgZ29mLmxhZyA9IDEwLCBtYWluID0gIkRpYWdub3N0aWNzIGZvciBBUigyKSIpCmNoZWNrcmVzaWR1YWxzKGFyX21vZGVsKQoKIyBRLVEgcGxvdCBmb3IgQVIoMikKcmVzaWR1YWxzX2FyMiA8LSByZXNpZHVhbHMoYXJfbW9kZWwpCnFxbm9ybShyZXNpZHVhbHNfYXIyLCBtYWluID0gIlEtUSBQbG90IG9mIFJlc2lkdWFscyBmb3IgQVIoMikiKQpxcWxpbmUocmVzaWR1YWxzX2FyMiwgY29sID0gInJlZCIpCmBgYAoKUS1RIFBsb3Q6CgotIFRoZSBwb2ludHMgaW4gdGhlIG1pZGRsZSBvZiB0aGUgcGxvdCBhcmUgY2xvc2VseSBhbGlnbmVkIHdpdGggdGhlIHJlZCBsaW5lLCBpbmRpY2F0aW5nIHRoYXQgdGhlIGNlbnRyYWwgcmVzaWR1YWxzIGFyZSBhcHByb3hpbWF0ZWx5IG5vcm1hbGx5IGRpc3RyaWJ1dGVkLgotIFRoZXJlIGlzIHNvbWUgZGV2aWF0aW9uIGF0IHRoZSB0YWlscyBvZiB0aGUgZGlzdHJpYnV0aW9uLCB3aXRoIHBvaW50cyBmYWxsaW5nIG9mZiB0aGUgbGluZSwgc3VnZ2VzdGluZyB0aGUgcHJlc2VuY2Ugb2Ygc29tZSBvdXRsaWVycyBvciBub24tbm9ybWFsaXR5IGluIHRoZSBleHRyZW1lIHZhbHVlcy4KLSBUaGUgUS1RIHBsb3QgaW5kaWNhdGVzIHRoYXQgd2hpbGUgbW9zdCByZXNpZHVhbHMgZm9sbG93IGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgdGhlIGV4dHJlbWUgdmFsdWVzIGRvIG5vdC4gVGhpcyBpcyBjb21tb24gaW4gZmluYW5jaWFsIGRhdGEgd2hlcmUgZXh0cmVtZSB2YWx1ZXMgKHZvbGF0aWxpdHkgY2x1c3RlcnMpIGFyZSBub3QgdW5jb21tb24uCgpSZXNpZHVhbHMgdnMuIFRpbWUgUGxvdDoKCi0gVGhlIHJlc2lkdWFscyBhcHBlYXIgdG8gYmUgcmFuZG9tbHkgc2NhdHRlcmVkIGFyb3VuZCB6ZXJvIHdpdGggbm8gZGlzY2VybmlibGUgcGF0dGVybiBvdmVyIHRpbWUuCi0gVGhpcyByYW5kb21uZXNzIHN1Z2dlc3RzIHRoYXQgdGhlIEFSKDIpIG1vZGVsIGhhcyBlZmZlY3RpdmVseSBjYXB0dXJlZCB0aGUgbGluZWFyIHBhdHRlcm5zIGluIHRoZSBkYXRhLCBsZWF2aW5nIHdoaXRlIG5vaXNlIHJlc2lkdWFscy4KCkFDRiBvZiBSZXNpZHVhbHM6CgotIFRoZSBhdXRvY29ycmVsYXRpb24gZnVuY3Rpb24gKEFDRikgb2YgdGhlIHJlc2lkdWFscyBzaG93cyB0aGF0IG1vc3Qgc3Bpa2VzIGFyZSB3aXRoaW4gdGhlIGNvbmZpZGVuY2UgYmFuZHMsIGluZGljYXRpbmcgbm8gc2lnbmlmaWNhbnQgYXV0b2NvcnJlbGF0aW9ucy4KLSBMYWNrIG9mIHNpZ25pZmljYW50IGF1dG9jb3JyZWxhdGlvbiBpbXBsaWVzIHRoYXQgdGhlcmUgYXJlIG5vIHBhdHRlcm5zIGxlZnQgdW5leHBsYWluZWQgYnkgdGhlIEFSKDIpIG1vZGVsLgoKSGlzdG9ncmFtIG9mIFJlc2lkdWFsczoKCi0gVGhlIGhpc3RvZ3JhbSB3aXRoIHRoZSBzdXBlcmltcG9zZWQgbm9ybWFsIGN1cnZlIHN1Z2dlc3RzIGEgc29tZXdoYXQgbm9ybWFsIGRpc3RyaWJ1dGlvbiBvZiByZXNpZHVhbHMsIGFsdGhvdWdoIHRoZXJlIG1pZ2h0IGJlIHNsaWdodCBza2V3bmVzcy4KLSBUaGlzIGZ1cnRoZXIgc3VwcG9ydHMgdGhlIGZpbmRpbmcgZnJvbSB0aGUgUS1RIHBsb3QgdGhhdCB0aGUgcmVzaWR1YWxzIGFyZSBhcHByb3hpbWF0ZWx5IG5vcm1hbCwgYnV0IHdpdGggc29tZSBkZXZpYXRpb25zIGF0IHRoZSB0YWlscy4KCkxqdW5nLUJveCBUZXN0OgoKLSBXaXRoIGEgcC12YWx1ZSBvZiAwLjE4ODksIHdlIGZhaWwgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMuIFRoaXMgaW5kaWNhdGVzIHRoYXQgdGhlIHJlc2lkdWFscyBkbyBub3QgZXhoaWJpdCBzaWduaWZpY2FudCBhdXRvY29ycmVsYXRpb24sIHN1Z2dlc3RpbmcgdGhhdCB0aGUgQVIoMikgbW9kZWwgZml0cyB0aGUgZGF0YSB3ZWxsIGluIHRlcm1zIG9mIGNhcHR1cmluZyB0aGUgdGVtcG9yYWwgZGVwZW5kZW5jaWVzLgoKCiMjIyMgTUEgTW9kZWwKYGBge3J9CiMgRml0IE1BIG1vZGVsCm1hX21vZGVsIDwtIEFyaW1hKGFhcGxtb250aGx5X3RzLCBvcmRlcj1jKDAsMCwyKSkKc3VtbWFyeShtYV9tb2RlbCkKYGBgCgoKCi0gVGhlIHNtYWxsIE1BKDEpIGNvZWZmaWNpZW50IHN1Z2dlc3RzIGEgd2VhayBpbXBhY3Qgb2YgdGhlIGVycm9yIGZyb20gb25lIHBlcmlvZCBhZ28sIHdoaWxlIHRoZSBtb2RlcmF0ZSBuZWdhdGl2ZSBNQSgyKSBjb2VmZmljaWVudCBpbmRpY2F0ZXMgYSBtb3JlIG5vdGljZWFibGUgaW52ZXJzZSByZWxhdGlvbnNoaXAgd2l0aCBlcnJvcnMgZnJvbSB0d28gcGVyaW9kcyBhZ28uCi0gVGhlIHZhcmlhbmNlIChzaWdtYV4yKSBpcyBtb2RlcmF0ZSwgY29uc2lzdGVudCB3aXRoIHRoZSBBUigyKSBtb2RlbCwgc3VnZ2VzdGluZyBhIHNpbWlsYXIgbGV2ZWwgb2YgdW5leHBsYWluZWQgdm9sYXRpbGl0eS4KLSBSTVNFIGFuZCBNQUUgYXJlIHNsaWdodGx5IGxvd2VyIHRoYW4gdGhvc2Ugb2YgdGhlIEFSKDIpIG1vZGVsLCBpbmRpY2F0aW5nIHRoYXQgdGhlIE1BKDIpIG1vZGVsIG1heSBmaXQgdGhlIGRhdGEgc2xpZ2h0bHkgYmV0dGVyIGluIHRlcm1zIG9mIGFic29sdXRlIGVycm9yIG1ldHJpY3MuCi0gVGhlIEFJQyBhbmQgQklDIHZhbHVlcyBhcmUgdmVyeSBzaW1pbGFyIHRvIHRob3NlIG9mIHRoZSBBUigyKSBtb2RlbCwgc3VnZ2VzdGluZyB0aGF0IGJvdGggbW9kZWxzIGFyZSBjb21wYXJhYmxlIGluIGZpdC4KLSBUaGUgc2xpZ2h0bHkgbG93ZXIgQUlDIHN1Z2dlc3RzIHRoZSBNQSgyKSBtb2RlbCBtaWdodCBiZSBtYXJnaW5hbGx5IGJldHRlciBpbiB0ZXJtcyBvZiBiYWxhbmNpbmcgbW9kZWwgY29tcGxleGl0eSBhbmQgZ29vZG5lc3Mgb2YgZml0LgoKCiMjIyMjIFJlc2lkdWFsIEFuYWx5c2lzCgpgYGB7cn0KIyBQZXJmb3JtIGRpYWdub3N0aWNzIGZvciBNQSgyKQpwYXIobWFyPWMoNSwgNSwgNCwgMikgKyAwLjEpCnRzZGlhZyhtYV9tb2RlbCwgZ29mLmxhZyA9IDEwLCBtYWluID0gIkRpYWdub3N0aWNzIGZvciBNQSgyKSIpCmNoZWNrcmVzaWR1YWxzKG1hX21vZGVsKQoKIyBRLVEgcGxvdCBmb3IgTUEoMikKcmVzaWR1YWxzX21hMiA8LSByZXNpZHVhbHMobWFfbW9kZWwpCnFxbm9ybShyZXNpZHVhbHNfbWEyLCBtYWluID0gIlEtUSBQbG90IG9mIFJlc2lkdWFscyBmb3IgTUEoMikiKQpxcWxpbmUocmVzaWR1YWxzX21hMiwgY29sID0gInJlZCIpCmBgYAoKUS1RIFBsb3Q6CgotIFRoZSBwbG90IHNob3dzIHRoYXQgdGhlIHJlc2lkdWFscyBjbG9zZWx5IGZvbGxvdyB0aGUgcmVkIGxpbmUgaW4gdGhlIG1pZGRsZSBzZWN0aW9uLCBzdWdnZXN0aW5nIHRoYXQgdGhlIHJlc2lkdWFscyBhcmUgYXBwcm94aW1hdGVseSBub3JtYWxseSBkaXN0cmlidXRlZC4KLSBIb3dldmVyLCB0aGVyZSBhcmUgZGV2aWF0aW9ucyBhdCB0aGUgdGFpbHMsIGluZGljYXRpbmcgcG90ZW50aWFsIGlzc3VlcyB3aXRoIG5vcm1hbGl0eSBhdCB0aGUgZXh0cmVtZXMgKG91dGxpZXJzKS4KClJlc2lkdWFscyB2cy4gVGltZSBQbG90OgoKLSBUaGUgcmVzaWR1YWxzIGFwcGVhciB0byBiZSBzY2F0dGVyZWQgcmFuZG9tbHkgYXJvdW5kIHplcm8sIGluZGljYXRpbmcgbm8gb2J2aW91cyBwYXR0ZXJucyBvciB0cmVuZHMuCi0gVGhpcyBzdWdnZXN0cyB0aGF0IHRoZSBtb2RlbCBoYXMgY2FwdHVyZWQgbW9zdCBvZiB0aGUgc3RydWN0dXJlIGluIHRoZSBkYXRhLgoKQUNGIG9mIFJlc2lkdWFsczoKCi0gTW9zdCBvZiB0aGUgc3Bpa2VzIGFyZSB3aXRoaW4gdGhlIGJsdWUgZGFzaGVkIGxpbmVzLCBpbmRpY2F0aW5nIHRoYXQgdGhlIHJlc2lkdWFscyBkbyBub3QgZXhoaWJpdCBzaWduaWZpY2FudCBhdXRvY29ycmVsYXRpb24uCi0gQSBmZXcgc3Bpa2VzIHNsaWdodGx5IGV4Y2VlZCB0aGUgYm91bmRzLCB3aGljaCBtYXkgaW5kaWNhdGUgc29tZSByZW1haW5pbmcgYXV0b2NvcnJlbGF0aW9uLCBidXQgaXQncyBub3Qgc3Vic3RhbnRpYWwuCgpIaXN0b2dyYW0gb2YgUmVzaWR1YWxzOgoKLSBUaGUgcmVzaWR1YWxzIGFwcGVhciB0byBmb2xsb3cgYSBiZWxsLXNoYXBlZCBjdXJ2ZSwgd2hpY2ggc3VnZ2VzdHMgYXBwcm94aW1hdGUgbm9ybWFsaXR5LgotIFRoZXJlIGlzIGEgc2xpZ2h0IHNrZXduZXNzLCBhcyBzZWVuIGJ5IHRoZSBtaXNtYXRjaCBiZXR3ZWVuIHRoZSBoaXN0b2dyYW0gYW5kIHRoZSBub3JtYWwgY3VydmUuCgpManVuZy1Cb3ggVGVzdDoKCi0gVGhlIHAtdmFsdWUgaXMgMC4xNDk5LCB3aGljaCBpcyBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBhdXRvY29ycmVsYXRpb24gaW4gdGhlIHJlc2lkdWFscy4gVGhlIG1vZGVsJ3MgcmVzaWR1YWxzIGNhbiBiZSBjb25zaWRlcmVkIGluZGVwZW5kZW50bHkgZGlzdHJpYnV0ZWQuCgoKCgojIyMjIEFSSU1BKDEsMSwxKSBNb2RlbCAKYGBge3J9CiMgRml0IEFSTUEoMSwxLDEpIG1vZGVsCmFybWFfbW9kZWwxIDwtIEFyaW1hKGFhcGxtb250aGx5X3RzLCBvcmRlcj1jKDEsMSwxKSkKc3VtbWFyeShhcm1hX21vZGVsMSkKYGBgCgoKCi0gVGhlIEFSIGNvZWZmaWNpZW50IGlzIHdlYWssIGluZGljYXRpbmcgYSBsaW1pdGVkIGVmZmVjdCBvZiBwYXN0IHZhbHVlcyBvbiBjdXJyZW50IHZhbHVlcy4gVGhlIE1BIGNvZWZmaWNpZW50IGlzIHZlcnkgc3Ryb25nLCBpbmRpY2F0aW5nIHNpZ25pZmljYW50IGNvcnJlY3Rpb24gYmFzZWQgb24gcGFzdCBlcnJvcnMuCi0gVGhlIGRpZmZlcmVuY2luZyBwYXJ0IG9mIHRoZSBBUklNQSBtb2RlbCBzdWdnZXN0cyB0aGF0IHRoZSBkYXRhIGhhcyBiZWVuIHRyYW5zZm9ybWVkIHRvIGFjaGlldmUgc3RhdGlvbmFyaXR5LCB3aGljaCBtaWdodCBleHBsYWluIHdoeSB0aGUgQVIgY29tcG9uZW50IGlzIHdlYWsuCi0gVGhlIHZhcmlhbmNlIG9mIHRoZSByZXNpZHVhbHMgaXMgbW9kZXJhdGUsIHN1Z2dlc3Rpbmcgc29tZSB1bmV4cGxhaW5lZCB2YXJpYWJpbGl0eSBpbiB0aGUgZGF0YS4KLSBSTVNFIGFuZCBNQUUgYXJlIGhpZ2hlciB0aGFuIGluIEFSKDIpIGFuZCBNQSgyKSwgaW5kaWNhdGluZyBsZXNzIHByZWNpc2UgcHJlZGljdGlvbnMuCi0gVGhlIEFJQyBhbmQgQklDIHZhbHVlcyBzdWdnZXN0IHRoaXMgbW9kZWwgbWlnaHQgbm90IGJlIHRoZSBiZXN0IGZpdCBjb21wYXJlZCB0byBzaW1wbGVyIG1vZGVscyBsaWtlIEFSKDIpIGFuZCBNQSgyKSwgd2hpY2ggaGFkIGxvd2VyIEFJQy9CSUMgdmFsdWVzLgoKCiMjIyMjIFJlc2lkdWFsIEFuYWx5c2lzCgpgYGB7cn0KIyBQZXJmb3JtIGRpYWdub3N0aWNzIGZvciBBUklNQSgxLDEsMSkKcGFyKG1hcj1jKDUsIDUsIDQsIDIpICsgMC4xKQp0c2RpYWcoYXJtYV9tb2RlbDEsIGdvZi5sYWcgPSAxMCwgbWFpbiA9ICJEaWFnbm9zdGljcyBmb3IgQVJJTUEoMSwxLDEpIikKY2hlY2tyZXNpZHVhbHMoYXJtYV9tb2RlbDEpCgojIFEtUSBwbG90IGZvciBBUklNQSgxLDEsMSkKcmVzaWR1YWxzX2FybWExMTEgPC0gcmVzaWR1YWxzKGFybWFfbW9kZWwxKQpxcW5vcm0ocmVzaWR1YWxzX2FybWExMTEsIG1haW4gPSAiUS1RIFBsb3Qgb2YgUmVzaWR1YWxzIGZvciBBUklNQSgxLDEsMSkiKQpxcWxpbmUocmVzaWR1YWxzX2FybWExMTEsIGNvbCA9ICJyZWQiKQpgYGAKClEtUSBQbG90OgoKLSBUaGUgcmVzaWR1YWxzIGFyZSBtb3N0bHkgYWxpZ25lZCB3aXRoIHRoZSBzdHJhaWdodCBsaW5lLCBzdWdnZXN0aW5nIHRoYXQgdGhleSBhcmUgYXBwcm94aW1hdGVseSBub3JtYWxseSBkaXN0cmlidXRlZC4KLSBIb3dldmVyLCB0aGVyZSBhcmUgc29tZSBkZXZpYXRpb25zIGF0IGJvdGggdGFpbHMsIGluZGljYXRpbmcgcG90ZW50aWFsIGlzc3VlcyB3aXRoIGV4dHJlbWUgdmFsdWVzIG9yIGhlYXZ5IHRhaWxzLgotIFRoZSBwbG90IGluZGljYXRlcyB0aGF0IHdoaWxlIG1vc3Qgb2YgdGhlIHJlc2lkdWFscyBmb2xsb3cgYSBub3JtYWwgZGlzdHJpYnV0aW9uLCB0aGVyZSBtYXkgYmUgc29tZSBleHRyZW1lIHZhbHVlcyAob3V0bGllcnMpIHRoYXQgZGV2aWF0ZSBmcm9tIHRoaXMgYXNzdW1wdGlvbi4KClJlc2lkdWFscyB2cy4gVGltZSBQbG90OgoKLSBUaGUgcmVzaWR1YWxzIGFwcGVhciB0byBiZSBjZW50ZXJlZCBhcm91bmQgemVybywgd2hpY2ggaXMgYSBnb29kIHNpZ24gZm9yIHVuYmlhc2VkIHByZWRpY3Rpb25zLgotIFRoZXJlIGFyZSBzb21lIHZpc2libGUgc3Bpa2VzIGFuZCB2YXJpYXRpb25zIG92ZXIgdGltZSwgd2hpY2ggY291bGQgaW5kaWNhdGUgbm9uLWNvbnN0YW50IHZhcmlhbmNlIG9yIHBvdGVudGlhbCBwYXR0ZXJucyBub3QgY2FwdHVyZWQgYnkgdGhlIG1vZGVsLgoKQUNGIG9mIFJlc2lkdWFsczoKCi0gVGhlIEFDRiB2YWx1ZXMgYXJlIG1vc3RseSB3aXRoaW4gdGhlIGJsdWUgZGFzaGVkIGxpbmVzIChjb25maWRlbmNlIGludGVydmFscyksIHN1Z2dlc3RpbmcgdGhhdCB0aGUgcmVzaWR1YWxzIGRvIG5vdCBleGhpYml0IHNpZ25pZmljYW50IGF1dG9jb3JyZWxhdGlvbi4KLSBUaGlzIGluZGljYXRlcyB0aGF0IHRoZSBBUklNQSgxLDEsMSkgbW9kZWwgaGFzIHN1Y2Nlc3NmdWxseSBjYXB0dXJlZCBtb3N0IG9mIHRoZSBhdXRvY29ycmVsYXRpb24gc3RydWN0dXJlIGluIHRoZSBkYXRhLgoKSGlzdG9ncmFtIG9mIFJlc2lkdWFsczoKCi0gVGhlIGRpc3RyaWJ1dGlvbiBhcHBlYXJzIHRvIGJlIGFwcHJveGltYXRlbHkgbm9ybWFsLCBidXQgd2l0aCBzbGlnaHQgc2tld25lc3MgYW5kIGt1cnRvc2lzLCBhcyBpbmRpY2F0ZWQgYnkgdGhlIGhpc3RvZ3JhbS4KLSBUaGVyZSBhcmUgc29tZSByZXNpZHVhbHMgb24gdGhlIHRhaWxzIHRoYXQgYXJlIGZ1cnRoZXIgYXdheSBmcm9tIHRoZSBub3JtYWwgY3VydmUsIHdoaWNoIGNvdWxkIGFmZmVjdCBtb2RlbCBhY2N1cmFjeSBmb3IgZXh0cmVtZSB2YWx1ZXMuCgpManVuZy1Cb3ggVGVzdDoKCi0gVGhlIGxvdyBwLXZhbHVlIHN1Z2dlc3RzIHRoYXQgdGhlcmUgaXMgc2lnbmlmaWNhbnQgYXV0b2NvcnJlbGF0aW9uIHByZXNlbnQgaW4gdGhlIHJlc2lkdWFscy4gVGhpcyBpbmRpY2F0ZXMgdGhhdCB0aGUgQVJJTUEoMSwxLDEpIG1vZGVsIG1heSBub3QgaGF2ZSBjYXB0dXJlZCBhbGwgdGhlIGF1dG9jb3JyZWxhdGlvbiBpbiB0aGUgZGF0YSwgbGVhZGluZyB0byBwb3RlbnRpYWwgaW1wcm92ZW1lbnQgaW4gbW9kZWwgZml0LgoKCgoKIyMjIyBBUklNQSgyLDEsMSkgTW9kZWwgCmBgYHtyfQojIEFSTUEoMiwxLDEpIE1vZGVsCmFybWFfbW9kZWwyIDwtIEFyaW1hKGFhcGxtb250aGx5X3RzLCBvcmRlcj1jKDIsMSwxKSkKc3VtbWFyeShhcm1hX21vZGVsMikKYGBgCgoKLSBUaGUgQVIgY29lZmZpY2llbnRzIHNob3cgYSBtaXhlZCBpbXBhY3QsIHdpdGggYSB3ZWFrIHBvc2l0aXZlIGVmZmVjdCBmcm9tIHRoZSBsYXN0IHBlcmlvZCBhbmQgYSBtb2RlcmF0ZSBuZWdhdGl2ZSBlZmZlY3QgZnJvbSB0d28gcGVyaW9kcyBhZ28uIFRoZSBzdHJvbmcgTUEoMSkgdGVybSBzdWdnZXN0cyB0aGF0IHJlY2VudCBlcnJvcnMgYXJlIGhlYXZpbHkgY29ycmVjdGVkLCB3aGljaCBtYXkgc21vb3RoIHRoZSBzZXJpZXMgdG9vIGFnZ3Jlc3NpdmVseS4KLSBUaGUgdmFyaWFuY2Ugb2YgdGhlIHJlc2lkdWFscyBpcyBtb2RlcmF0ZSwgaW5kaWNhdGluZyBhIGZhaXIgYW1vdW50IG9mIGV4cGxhaW5lZCB2YXJpYWJpbGl0eS4gVGhlIGVycm9yIG1lYXN1cmVzIChSTVNFIGFuZCBNQUUpIHN1Z2dlc3QgdGhhdCB0aGUgbW9kZWwgcHJvdmlkZXMgcmVhc29uYWJseSBhY2N1cmF0ZSBwcmVkaWN0aW9ucywgYWx0aG91Z2ggdGhlcmUgYXJlIHN0aWxsIGFyZWFzIGZvciBpbXByb3ZlbWVudC4KLSBUaGUgQUlDIGFuZCBCSUMgdmFsdWVzIGFyZSByZWxhdGl2ZWx5IGxvdywgaW5kaWNhdGluZyBhIGdvb2QgZml0IGNvbXBhcmVkIHRvIG90aGVyIG1vZGVscy4gVGhlIGxvZyBsaWtlbGlob29kIGlzIGFsc28gaGlnaGVyLCBzdXBwb3J0aW5nIHRoaXMgY29uY2x1c2lvbi4KLSBUaGUgQVJJTUEoMiwxLDEpIG1vZGVsIGNhcHR1cmVzIHRoZSBkYXRhIGR5bmFtaWNzIHdlbGwsIHdpdGggc3Ryb25nIGNvcnJlY3Rpb24gZm9yIHBhc3QgZXJyb3JzIGFuZCBhIHJlYXNvbmFibGUgYWNjb3VudCBvZiBwYXN0IHZhbHVlcy4gVGhlIG1vZGVsIGlzIGVmZmVjdGl2ZSBpbiBoYW5kbGluZyB0aGUgZGF0YSdzIHN0cnVjdHVyZSBhbmQgdHJlbmRzLCBhcyBpbmRpY2F0ZWQgYnkgdGhlIGxvdyBlcnJvciBtZWFzdXJlcyBhbmQgQUNGMS4KCgojIyMjIyBSZXNpZHVhbCBBbmFseXNpcwoKYGBge3J9CiMgUGVyZm9ybSBkaWFnbm9zdGljcyBmb3IgQVJJTUEoMiwxLDEpCnBhcihtYXI9Yyg1LCA1LCA0LCAyKSArIDAuMSkKdHNkaWFnKGFybWFfbW9kZWwyLCBnb2YubGFnID0gMTAsIG1haW4gPSAiRGlhZ25vc3RpY3MgZm9yIEFSSU1BKDIsMSwxKSIpCmNoZWNrcmVzaWR1YWxzKGFybWFfbW9kZWwyKQoKIyBRLVEgcGxvdCBmb3IgQVJJTUEoMiwxLDEpCnJlc2lkdWFsc19hcm1hMjExIDwtIHJlc2lkdWFscyhhcm1hX21vZGVsMikKcXFub3JtKHJlc2lkdWFsc19hcm1hMjExLCBtYWluID0gIlEtUSBQbG90IG9mIFJlc2lkdWFscyBmb3IgQVJJTUEoMiwxLDEpIikKcXFsaW5lKHJlc2lkdWFsc19hcm1hMjExLCBjb2wgPSAicmVkIikKYGBgCgoKUS1RIFBsb3Q6CgotIFRoZSByZXNpZHVhbHMgYXJlIGNsb3NlIHRvIHRoZSBsaW5lLCBlc3BlY2lhbGx5IGluIHRoZSBtaWRkbGUgcmFuZ2UsIGluZGljYXRpbmcgdGhhdCB0aGV5IGFyZSBhcHByb3hpbWF0ZWx5IG5vcm1hbGx5IGRpc3RyaWJ1dGVkLgotIFRoZSB0YWlscyBkZXZpYXRlIHNsaWdodGx5IGZyb20gdGhlIGxpbmUsIHN1Z2dlc3RpbmcgcG90ZW50aWFsIG91dGxpZXJzIG9yIG5vbi1ub3JtYWxpdHkgaW4gdGhlIGV4dHJlbWVzLiBUaGlzIGlzIGNvbW1vbiBpbiBmaW5hbmNpYWwgZGF0YS4KClJlc2lkdWFscyB2cy4gVGltZSBQbG90OgoKLSBUaGUgcmVzaWR1YWxzIGZsdWN0dWF0ZSBhcm91bmQgemVybywgaW5kaWNhdGluZyB0aGF0IHRoZSBtb2RlbCBoYXMgY2FwdHVyZWQgdGhlIHRyZW5kIHdlbGwuCi0gVGhlIHZhcmlhbmNlIG9mIHJlc2lkdWFscyBhcHBlYXJzIGNvbnN0YW50IG92ZXIgdGltZSwgd2hpY2ggc2F0aXNmaWVzIG9uZSBvZiB0aGUgYXNzdW1wdGlvbnMgb2YgQVJJTUEgbW9kZWxpbmcuCi0gVGhlcmUgYXJlIG5vIG9idmlvdXMgcGF0dGVybnMsIHN1Z2dlc3RpbmcgdGhlIG1vZGVsIGlzIGNhcHR1cmluZyBtb3N0IG9mIHRoZSBzaWduYWwuCgpBQ0Ygb2YgUmVzaWR1YWxzOgoKLSBUaGUgbWFqb3JpdHkgb2YgdGhlIGF1dG9jb3JyZWxhdGlvbiB2YWx1ZXMgZmFsbCB3aXRoaW4gdGhlIGJsdWUgY29uZmlkZW5jZSBiYW5kcywgaW5kaWNhdGluZyBubyBzaWduaWZpY2FudCBhdXRvY29ycmVsYXRpb24uCi0gVGhpcyBzdWdnZXN0cyB0aGF0IHRoZSBtb2RlbCBoYXMgZWZmZWN0aXZlbHkgY2FwdHVyZWQgdGhlIGF1dG9jb3JyZWxhdGlvbnMgaW4gdGhlIGRhdGEuCgpIaXN0b2dyYW0gb2YgUmVzaWR1YWxzOgoKLSBUaGUgaGlzdG9ncmFtIHNob3dzIGEgYmVsbC1zaGFwZWQgY3VydmUsIHdpdGggc29tZSBkZXZpYXRpb24gYXQgdGhlIHRhaWxzLCB3aGljaCBpcyB0eXBpY2FsIGZvciB0aW1lIHNlcmllcyBkYXRhLgotIFRoZSBvdmVybGF5aW5nIG5vcm1hbCBjdXJ2ZSBmaXRzIHJlYXNvbmFibHkgd2VsbCwgc3VnZ2VzdGluZyByZXNpZHVhbHMgYXJlIGFwcHJveGltYXRlbHkgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuCgpManVuZy1Cb3ggVGVzdDoKCi0gVGhlIHAtdmFsdWUgaXMgZ3JlYXRlciB0aGFuIDAuMDUsIGluZGljYXRpbmcgdGhhdCB3ZSBmYWlsIHRvIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIG9mIG5vIGF1dG9jb3JyZWxhdGlvbiBpbiB0aGUgcmVzaWR1YWxzLiBUaGlzIG1lYW5zIHRoZSByZXNpZHVhbHMgYXJlIGxpa2VseSByYW5kb20sIHN1cHBvcnRpbmcgdGhlIG1vZGVsJ3MgYWRlcXVhY3kuCgoKCgojIyMjIEFSSU1BKDIsMSwyKSBNb2RlbCAKYGBge3J9CiMgQVJNQSgyLDEsMikgTW9kZWwKYXJtYV9tb2RlbDMgPC0gQXJpbWEoYWFwbG1vbnRobHlfdHMsIG9yZGVyPWMoMiwxLDIpKQpzdW1tYXJ5KGFybWFfbW9kZWwzKQpgYGAKCgotIFRoZSBBUigyKSB0ZXJtIHNlZW1zIHNpZ25pZmljYW50LCB3aGlsZSB0aGUgQVIoMSkgYW5kIE1BKDIpIHRlcm1zIGFyZSBsZXNzIGltcGFjdGZ1bC4gVGhlIE1BKDEpIHRlcm0gaXMgc3Ryb25nLCBzdWdnZXN0aW5nIHJlbGlhbmNlIG9uIGNvcnJlY3RpbmcgdGhlIHByZXZpb3VzIHBlcmlvZCdzIGVycm9yLgotIFRoZSByZXNpZHVhbCB2YXJpYW5jZSAoc2lnbWFeMikgaXMgc2xpZ2h0bHkgaGlnaGVyIHRoYW4gZGVzaXJlZCwgaW5kaWNhdGluZyBzb21lIHVuZXhwbGFpbmVkIHZhcmlhYmlsaXR5LiBUaGUgQUNGMSBpcyBjbG9zZSB0byB6ZXJvLCB3aGljaCBpcyBwb3NpdGl2ZSwgaW5kaWNhdGluZyBsaXR0bGUgcmVtYWluaW5nIGF1dG9jb3JyZWxhdGlvbi4KLSBDb21wYXJlZCB0byB0aGUgQVJJTUEoMiwxLDEpIG1vZGVsLCB0aGlzIG1vZGVsIGhhcyBzbGlnaHRseSBoaWdoZXIgQUlDIGFuZCBCSUMsIHN1Z2dlc3RpbmcgaXQgbWlnaHQgbm90IGZpdCBhcyB3ZWxsLiBIb3dldmVyLCB0aGUgcGVyZm9ybWFuY2UgbWV0cmljcyAoUk1TRSwgTUFFKSBhcmUgY29tcGV0aXRpdmUsIGluZGljYXRpbmcgdGhpcyBtb2RlbCBpcyBhbHNvIGEgdmFsaWQgY2FuZGlkYXRlLgotIFdoaWxlIHRoZSBlcnJvciBtZWFzdXJlcyAoTUFQRSwgTVBFKSBzaG93IHNvbWUgcHJlZGljdGlvbiBlcnJvcnMsIHRoZSBtb2RlbCBjYXB0dXJlcyB0aGUgZ2VuZXJhbCB0cmVuZCB3ZWxsLiBJbXByb3ZlbWVudHMgY291bGQgYmUgbWFkZSBieSByZWZpbmluZyB0aGUgbW9kZWwgb3IgdGVzdGluZyBhbHRlcm5hdGl2ZSBzcGVjaWZpY2F0aW9ucy4KCgoKIyMjIyMgUmVzaWR1YWwgQW5hbHlzaXMKCmBgYHtyfQojIFBlcmZvcm0gZGlhZ25vc3RpY3MgZm9yIEFSSU1BKDIsMSwyKQpwYXIobWFyPWMoNSwgNSwgNCwgMikgKyAwLjEpCnRzZGlhZyhhcm1hX21vZGVsMywgZ29mLmxhZyA9IDEwLCBtYWluID0gIkRpYWdub3N0aWNzIGZvciBBUklNQSgyLDEsMikiKQpjaGVja3Jlc2lkdWFscyhhcm1hX21vZGVsMykKCiMgUS1RIHBsb3QgZm9yIEFSSU1BKDIsMSwyKQpyZXNpZHVhbHNfYXJtYTIxMiA8LSByZXNpZHVhbHMoYXJtYV9tb2RlbDMpCnFxbm9ybShyZXNpZHVhbHNfYXJtYTIxMiwgbWFpbiA9ICJRLVEgUGxvdCBvZiBSZXNpZHVhbHMgZm9yIEFSSU1BKDIsMSwyKSIpCnFxbGluZShyZXNpZHVhbHNfYXJtYTIxMiwgY29sID0gInJlZCIpCmBgYAoKCgpRLVEgUGxvdDoKCi0gVGhlIHJlc2lkdWFscyBhcmUgY2xvc2UgdG8gdGhlIGxpbmUsIGVzcGVjaWFsbHkgaW4gdGhlIG1pZGRsZSByYW5nZSwgaW5kaWNhdGluZyB0aGF0IHRoZXkgYXJlIGFwcHJveGltYXRlbHkgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuCi0gVGhlIHRhaWxzIGRldmlhdGUgc2xpZ2h0bHkgZnJvbSB0aGUgbGluZSwgc3VnZ2VzdGluZyBwb3RlbnRpYWwgb3V0bGllcnMgb3Igbm9uLW5vcm1hbGl0eSBpbiB0aGUgZXh0cmVtZXMuIFRoaXMgaXMgY29tbW9uIGluIGZpbmFuY2lhbCBkYXRhLgoKUmVzaWR1YWxzIHZzLiBUaW1lIFBsb3Q6CgotIFRoZSByZXNpZHVhbHMgZmx1Y3R1YXRlIGFyb3VuZCB6ZXJvLCBpbmRpY2F0aW5nIHRoYXQgdGhlIEFSSU1BKDIsMSwyKSBtb2RlbCBoYXMgc3VjY2Vzc2Z1bGx5IGNhcHR1cmVkIHRoZSBtYWluIHN0cnVjdHVyZSBvZiB0aGUgZGF0YS4KLSBUaGVyZSBhcmUgbm8gb2J2aW91cyBwYXR0ZXJucyBvciB0cmVuZHMgdmlzaWJsZSwgc3VnZ2VzdGluZyB0aGF0IHRoZSBtb2RlbCBhY2NvdW50cyB3ZWxsIGZvciB0aGUgc3lzdGVtYXRpYyBjb21wb25lbnRzIG9mIHRoZSB0aW1lIHNlcmllcy4KLSBUaGUgbW9kZWwgYXBwZWFycyB0byBjYXB0dXJlIHRoZSBkeW5hbWljcyBvZiB0aGUgZGF0YSB3ZWxsLCB3aXRoIHJlc2lkdWFscyB0aGF0IHJlc2VtYmxlIHdoaXRlIG5vaXNlLgoKQUNGIG9mIFJlc2lkdWFsczoKCi0gTW9zdCBhdXRvY29ycmVsYXRpb24gdmFsdWVzIGxpZSB3aXRoaW4gdGhlIGJsdWUgZGFzaGVkIGNvbmZpZGVuY2UgYm91bmRzLCB3aGljaCBzdWdnZXN0cyB0aGF0IHRoZSByZXNpZHVhbHMgYXJlIHVuY29ycmVsYXRlZC4KLSBUaGUgbGFjayBvZiBzaWduaWZpY2FudCBhdXRvY29ycmVsYXRpb24gaW5kaWNhdGVzIHRoYXQgdGhlIG1vZGVsIGhhcyBlZmZlY3RpdmVseSBjYXB0dXJlZCB0aGUgYXV0b2NvcnJlbGF0aW9uIHN0cnVjdHVyZSBvZiB0aGUgc2VyaWVzLCByZXN1bHRpbmcgaW4gcmVzaWR1YWxzIHRoYXQgYXJlIGNsb3NlIHRvIHdoaXRlIG5vaXNlLgoKSGlzdG9ncmFtIG9mIFJlc2lkdWFsczoKCi0gVGhlIHJlc2lkdWFscyBzaG93IGEgZGlzdHJpYnV0aW9uIHRoYXQgaXMgZmFpcmx5IHN5bW1ldHJpYywgdGhvdWdoIHRoZXJlIG1pZ2h0IGJlIHNvbWUgc2tld25lc3Mgb3Iga3VydG9zaXMuCi0gVGhlIHJlc2lkdWFscycgZGlzdHJpYnV0aW9uIGlzIGZhaXJseSBub3JtYWwgYnV0IHdpdGggc2xpZ2h0IGRldmlhdGlvbnMsIGxpa2VseSBkdWUgdG8gb3V0bGllcnMgb3IgbW9kZWwgaW1wZXJmZWN0aW9ucy4KCkxqdW5nLUJveCBUZXN0OgoKLSBTaW5jZSB0aGUgcC12YWx1ZSBpcyBncmVhdGVyIHRoYW4gMC4wNSwgd2UgZmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBvZiBubyBhdXRvY29ycmVsYXRpb24sIHN1Z2dlc3RpbmcgdGhhdCB0aGUgcmVzaWR1YWxzIGFyZSBpbmRlZWQgd2hpdGUgbm9pc2UuCgoKCgojIyMjIEdBUkNIIE1vZGVscwoKYGBge3J9CiMgQ3JlYXRlIGEgdGltZSBzZXJpZXMgb2JqZWN0CmFhcGxtb250aGx5X3RzMiA8LSB0cyhhYXBsX21vbnRobHlfZGF0YSRDbG9zZSwgc3RhcnQ9YygyMDE2LCAwMSksIGVuZCA9IGMoMjAyNCwgMDUpLCBmcmVxdWVuY3k9MTIpIAojIENhbGN1bGF0ZSByZXR1cm5zIGZvciBtb2RlbGluZwpyZXR1cm5zIDwtIGRpZmYobG9nKGFhcGxtb250aGx5X3RzMikpCnJldHVybnMgPC0gcmV0dXJuc1shaXMubmEocmV0dXJucyldCnBsb3QocmV0dXJucywgbWFpbj0iTW9udGhseSBBcHBsZSBTdG9jayBQcmljZXMiLCB5bGFiPSJDbG9zZSBQcmljZSIsIHhsYWI9IlRpbWUiLCB0eXBlPSJsIikKYGBgCgoKCgpgYGB7cn0KIyBTcGVjaWZ5IEdBUkNIKDEsMSkgbW9kZWwKc3BlY19nYXJjaCA8LSB1Z2FyY2hzcGVjKHZhcmlhbmNlLm1vZGVsID0gbGlzdChtb2RlbCA9ICJzR0FSQ0giLCBnYXJjaE9yZGVyID0gYygxLCAxKSksCiAgICAgICAgICAgICAgICAgICAgICAgICBtZWFuLm1vZGVsID0gbGlzdChhcm1hT3JkZXIgPSBjKDEsIDApKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBkaXN0cmlidXRpb24ubW9kZWwgPSAibm9ybSIpCgpmaXRfZ2FyY2ggPC0gdWdhcmNoZml0KHNwZWMgPSBzcGVjX2dhcmNoLCBkYXRhID0gcmV0dXJucykKCiMgRGlzcGxheSB0aGUgZml0IHN1bW1hcnkKZml0X2dhcmNoCmBgYAoKCgpgYGB7cn0KIyBTcGVjaWZ5IEdBUkNIKDEsMSkgbW9kZWwKc3BlY19nYXJjaCA8LSB1Z2FyY2hzcGVjKHZhcmlhbmNlLm1vZGVsID0gbGlzdChtb2RlbCA9ICJzR0FSQ0giLCBnYXJjaE9yZGVyID0gYygxLCAxKSksCiAgICAgICAgICAgICAgICAgICAgICAgICBtZWFuLm1vZGVsID0gbGlzdChhcm1hT3JkZXIgPSBjKDIsIDEpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBkaXN0cmlidXRpb24ubW9kZWwgPSAibm9ybSIpCgpmaXRfZ2FyY2ggPC0gdWdhcmNoZml0KHNwZWMgPSBzcGVjX2dhcmNoLCBkYXRhID0gcmV0dXJucykKCiMgRGlzcGxheSB0aGUgZml0IHN1bW1hcnkKZml0X2dhcmNoCmBgYAoKTW9kZWwgRml0OgoKLSBUaGUgR0FSQ0goMSwxKSB3aXRoIEFSRklNQSgxLDAsMCkgbWVhbiBlcXVhdGlvbiBwcm92aWRlcyBhIHJlYXNvbmFibGUgZml0IHRvIHRoZSBkYXRhLiBUaGUgaGlnaCBzaWduaWZpY2FuY2Ugb2YgdGhlICRcYmV0YV8xJCBwYXJhbWV0ZXIgaGlnaGxpZ2h0cyB0aGUgaW1wb3J0YW5jZSBvZiBwYXN0IHZvbGF0aWxpdHkgaW4gZXhwbGFpbmluZyBjdXJyZW50IHZvbGF0aWxpdHkuCi0gVGhlIGFic2VuY2Ugb2Ygc2lnbmlmaWNhbnQgc2VyaWFsIGNvcnJlbGF0aW9uIGluIGJvdGggcmF3IGFuZCBzcXVhcmVkIHJlc2lkdWFscyBpbmRpY2F0ZXMgdGhhdCB0aGUgbW9kZWwgY2FwdHVyZXMgdGhlIGF1dG9jb3JyZWxhdGlvbiBhbmQgdm9sYXRpbGl0eSBjbHVzdGVyaW5nIGVmZmVjdGl2ZWx5LgotIFRoZSBwLXZhbHVlcyBmcm9tIHRoZSBkaWFnbm9zdGljIHRlc3RzIHN1Z2dlc3QgdGhhdCB0aGUgcmVzaWR1YWxzIGFwcHJveGltYXRlIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgbWFraW5nIHRoZSBtb2RlbCBzdWl0YWJsZSBmb3IgdGhlIGRhdGEuCi0gVGhlIHN0YWJpbGl0eSBvZiBpbmRpdmlkdWFsIHBhcmFtZXRlcnMgc3VnZ2VzdHMgdGhlIG1vZGVsJ3Mgcm9idXN0bmVzcyBvdmVyIHRpbWUsIHRob3VnaCB0aGVyZSBpcyBhIHNsaWdodCBpbmRpY2F0aW9uIG9mIG92ZXJhbGwgaW5zdGFiaWxpdHkuCi0gVGhlIG1vZGVsIGlzIHVzZWZ1bCBmb3IgZm9yZWNhc3RpbmcgZnV0dXJlIHZvbGF0aWxpdHkgYW5kIGNhcHR1cmluZyB0aGUgdm9sYXRpbGl0eSBjbHVzdGVyaW5nIHR5cGljYWwgaW4gZmluYW5jaWFsIHRpbWUgc2VyaWVzIGxpa2Ugc3RvY2sgcHJpY2VzLgoKCgoKYGBge3J9CiMgUGxvdCBkaWFnbm9zdGljcwpwbG90KGZpdF9nYXJjaCkKYGBgCgpOZXdzIEltcGFjdCBDdXJ2ZToKCi0gVGhlIGN1cnZlIGlzIHN5bW1ldHJpY2FsLCBpbmRpY2F0aW5nIHRoYXQgYm90aCBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgc2hvY2tzIG9mIGVxdWFsIG1hZ25pdHVkZSBoYXZlIGEgc2ltaWxhciBpbXBhY3Qgb24gdm9sYXRpbGl0eS4KLSBUaGUgVS1zaGFwZSBzaG93cyB0aGF0IGJvdGggcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIHJldHVybnMgaW5jcmVhc2Ugdm9sYXRpbGl0eSBlcXVhbGx5LCB3aGljaCBpcyB0eXBpY2FsIGZvciBzeW1tZXRyaWMgR0FSQ0ggbW9kZWxzLgoKQUNGIG9mIFNxdWFyZWQgU3RhbmRhcmRpemVkIFJlc2lkdWFsczoKCi0gTW9zdCBvZiB0aGUgYXV0b2NvcnJlbGF0aW9uIHZhbHVlcyBmYWxsIHdpdGhpbiB0aGUgY29uZmlkZW5jZSBiYW5kcywgaW5kaWNhdGluZyBubyBzaWduaWZpY2FudCBhdXRvY29ycmVsYXRpb24gaW4gdGhlIHNxdWFyZWQgcmVzaWR1YWxzLiAKLSBUaGlzIHN1Z2dlc3RzIHRoYXQgdGhlIEdBUkNIIG1vZGVsIGhhcyBzdWNjZXNzZnVsbHkgY2FwdHVyZWQgdGhlIHZvbGF0aWxpdHkgY2x1c3RlcmluZyBpbiB0aGUgZGF0YSwgbWVhbmluZyB0aGUgbW9kZWwncyB2b2xhdGlsaXR5IHN0cnVjdHVyZSBpcyBhZGVxdWF0ZS4KCkFDRiBvZiBTdGFuZGFyZGl6ZWQgUmVzaWR1YWxzOgoKLSAgVGhlIHJlc2lkdWFscyBhcHBlYXIgdG8gYmUgd2hpdGUgbm9pc2Ugc2luY2UgbW9zdCBhdXRvY29ycmVsYXRpb25zIGxpZSB3aXRoaW4gdGhlIGNvbmZpZGVuY2UgYmFuZHMuIAotIFRoaXMgc3VnZ2VzdHMgdGhlIG1lYW4gZXF1YXRpb24gcGFydCBvZiB0aGUgQVJGSU1BLUdBUkNIIG1vZGVsIGhhcyBiZWVuIHdlbGwgc3BlY2lmaWVkIGFuZCBjYXB0dXJlcyB0aGUgZGF0YSdzIGR5bmFtaWNzIGVmZmVjdGl2ZWx5LgoKUS1RIFBsb3Q6CgotIFRoZSBwb2ludHMgbGFyZ2VseSBmb2xsb3cgdGhlIGxpbmUsIGluZGljYXRpbmcgdGhlIHJlc2lkdWFscyBhcmUgYXBwcm94aW1hdGVseSBub3JtYWxseSBkaXN0cmlidXRlZC4gU29tZSBkZXZpYXRpb25zIGF0IHRoZSB0YWlscyBtaWdodCBzdWdnZXN0IHBvdGVudGlhbCBmYXQgdGFpbHMuCgpFbXBpcmljYWwgRGVuc2l0eSBvZiBTdGFuZGFyZGl6ZWQgUmVzaWR1YWxzOgoKLSBUaGUgcmVzaWR1YWxzIGNsb3NlbHkgZm9sbG93IGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgaW1wbHlpbmcgdGhhdCB0aGUgbW9kZWwgZG9lcyBub3QgaGF2ZSBzaWduaWZpY2FudCBtaXNzcGVjaWZpY2F0aW9uIGluIHRlcm1zIG9mIGRpc3RyaWJ1dGlvbmFsIGFzc3VtcHRpb25zLgoKQ3Jvc3MtQ29ycmVsYXRpb25zIG9mIFNxdWFyZWQgdnMuIEFjdHVhbCBPYnNlcnZhdGlvbnM6CgotIElkZWFsbHksIHRoZXJlIHNob3VsZCBiZSBubyBzaWduaWZpY2FudCBjb3JyZWxhdGlvbiwgaW1wbHlpbmcgdGhhdCB0aGUgc3F1YXJlZCByZXR1cm5zIChwcm94eSBmb3Igdm9sYXRpbGl0eSkgZG8gbm90IHNob3cgZnVydGhlciBwcmVkaWN0YWJsZSBwYXR0ZXJucy4KLSBUaGUgb25lIHNpZ25pZmljYW50IGJhciBpbmRpY2F0ZXMgYSBwb3RlbnRpYWwgYWRkaXRpb25hbCBwYXR0ZXJuIHRoZSBtb2RlbCBoYXNuJ3QgY2FwdHVyZWQuCgpBQ0Ygb2YgQWJzb2x1dGUgT2JzZXJ2YXRpb25zOgoKLSBBYnNlbmNlIG9mIHNpZ25pZmljYW50IGF1dG9jb3JyZWxhdGlvbnMgaW5kaWNhdGVzIHRoYXQgdGhlIEdBUkNIIG1vZGVsIGFkZXF1YXRlbHkgY2FwdHVyZXMgdm9sYXRpbGl0eSBjbHVzdGVyaW5nLgoKQUNGIG9mIFNxdWFyZWQgT2JzZXJ2YXRpb25zOgoKLSBUaGUgbGFjayBvZiBzaWduaWZpY2FudCBhdXRvY29ycmVsYXRpb24gaW1wbGllcyB0aGF0IHRoZSBtb2RlbCBoYXMgY2FwdHVyZWQgdGhlIHNlcmlhbCBkZXBlbmRlbmNlIGluIHRoZSB2b2xhdGlsaXR5IG9mIHRoZSBzZXJpZXMuCgpBQ0Ygb2YgT2JzZXJ2YXRpb25zOgoKLSAgTGFjayBvZiBzaWduaWZpY2FudCBhdXRvY29ycmVsYXRpb24gaW5kaWNhdGVzIHRoYXQgdGhlIG1lYW4gbW9kZWwgaXMgY2FwdHVyaW5nIHRoZSBkeW5hbWljcyBlZmZlY3RpdmVseSwgc3VnZ2VzdGluZyBhbiBhZGVxdWF0ZSBBUkZJTUEgZml0LgoKQ29uZGl0aW9uYWwgU3RhbmRhcmQgRGV2aWF0aW9uIHZzLiBSZXR1cm5zOgoKLSBUaGUgcGxvdCByZXZlYWxzIHRoZSBtb2RlbCdzIGFiaWxpdHkgdG8gdHJhY2sgcGVyaW9kcyBvZiBoaWdoIGFuZCBsb3cgdm9sYXRpbGl0eS4gSWYgdGhlIEdBUkNIIG1vZGVsIGlzIGNhcHR1cmluZyB0aGUgdGltZS12YXJ5aW5nIHZvbGF0aWxpdHkgYWRlcXVhdGVseSwgdGhlIGNvbmRpdGlvbmFsIFNEIHNob3VsZCBtYXRjaCBwZXJpb2RzIG9mIGhpZ2ggcmV0dXJucyB2YXJpYW5jZS4KClNlcmllcyB3aXRoIDIgQ29uZGl0aW9uYWwgU0QgU3VwZXJpbXBvc2VkOgoKLSBUaGUgcmVkIGxpbmVzIHJlcHJlc2VudCB0aGUgMiBjb25kaXRpb25hbCBzdGFuZGFyZCBkZXZpYXRpb25zIGFib3ZlIGFuZCBiZWxvdyB0aGUgbWVhbi4gCi0gVGhlIG1vZGVsIGZpdHMgd2VsbCwgbW9zdCBvZiB0aGUgZGF0YSBwb2ludHMgc2hvdWxkIGZhbGwgd2l0aGluIHRoZXNlIGJvdW5kcywgaW5kaWNhdGluZyB0aGF0IHRoZSBtb2RlbCBhY2N1cmF0ZWx5IGNhcHR1cmVzIHRoZSB2b2xhdGlsaXR5IGluIHRoZSBkYXRhLgoKU2VyaWVzIHdpdGggMSUgVmFSIExpbWl0czoKCi0gVGhlIGdyZWVuIGFuZCByZWQgbGluZXMgcmVwcmVzZW50IHRoZSB1cHBlciBhbmQgbG93ZXIgVmFSIGxpbWl0cywgcmVzcGVjdGl2ZWx5LiAKLSBPdmVyYWxsIHRoZSBtb2RlbCBmaXRzIHdlbGwsIHRoZSByZXR1cm5zIHJhcmVseSBleGNlZWQgdGhlc2UgbGltaXRzLCBpbmRpY2F0aW5nIHRoYXQgdGhlIG1vZGVsIHByb3ZpZGVzIGEgZ29vZCBlc3RpbWF0ZSBvZiB0aGUgcmlzay4KCgoKCiMjIyMgRm9yZWNhc3RpbmcKCmBgYHtyfQojIEZvcmVjYXN0aW5nIHdpdGggdGhlIEdBUkNIIG1vZGVsCmZvcmVjYXN0X2dhcmNoIDwtIHVnYXJjaGZvcmVjYXN0KGZpdF9nYXJjaCwgbi5haGVhZD0xMikKcGxvdChmb3JlY2FzdF9nYXJjaCwgd2hpY2g9MSkgICMgRm9yZWNhc3Qgc2VyaWVzCmBgYAoKLSBUaGUgZm9yZWNhc3RlZCB2YWx1ZXMgYXJlIHByZXR0eSBjbG9zZSB0byB0aGUgYWN0dWFsIGhpc3RvcmljYWwgdmFsdWVzIHRvd2FyZHMgdGhlIGVuZCBvZiB0aGUgdGltZSBzZXJpZXMKLSBUaGUgdGhlIHJlZCBsaW5lIGFwcGVhcnMgcmVsYXRpdmVseSBzdGFibGUgY29tcGFyZWQgdG8gdGhlIGhpc3RvcmljYWwgc2VyaWVzLCBpbmRpY2F0aW5nIHRoYXQgdGhlIG1vZGVsIGV4cGVjdHMgdGhlIGZ1dHVyZSByZXR1cm5zIHRvIHN0YWJpbGl6ZSBzb21ld2hhdCwgd2l0aCBsZXNzIGV4dHJlbWUgZmx1Y3R1YXRpb25zIHRoYW4gb2JzZXJ2ZWQgaW4gdGhlIHBhc3QuCi0gVGhlIHllbGxvdyBiYW5kcyB3aWRlbiBhcyB0aGUgZm9yZWNhc3QgaG9yaXpvbiBleHRlbmRzLCB3aGljaCBpcyB0eXBpY2FsIGluIHRpbWUgc2VyaWVzIGZvcmVjYXN0aW5nLiBUaGlzIHdpZGVuaW5nIGluZGljYXRlcyB0aGF0IHVuY2VydGFpbnR5IGluY3JlYXNlcyB0aGUgZnVydGhlciBpbnRvIHRoZSBmdXR1cmUgd2UgcHJlZGljdC4gVGhlIGFjdHVhbCByZXR1cm5zIG1heSBkZXZpYXRlIHNpZ25pZmljYW50bHkgZnJvbSB0aGUgZm9yZWNhc3RlZCBsaW5lLCBlc3BlY2lhbGx5IGFzIHdlIG1vdmUgZnVydGhlciBpbnRvIHRoZSBmb3JlY2FzdCBob3Jpem9uLgotIFNpbmNlIHRoZSBoaXN0b3JpY2FsIHNlcmllcyBlbmRzIHdpdGhpbiB0aGUgcmVkIGxpbmUgYW5kIHllbGxvdyBiYW5kcywgaXQgc3VnZ2VzdHMgdGhhdCB0aGUgbW9kZWwgaXMgY2FwdHVyaW5nIHRoZSBjZW50cmFsIHRlbmRlbmN5IG9mIHRoZSB0aW1lIHNlcmllcyB3ZWxsLiBIb3dldmVyLCB0aGUgaW5jcmVhc2luZyB3aWR0aCBvZiB0aGUgYmFuZHMgaGlnaGxpZ2h0cyB0aGF0IHdoaWxlIHRoZSBtb2RlbCBleHBlY3RzIGxlc3Mgdm9sYXRpbGl0eSwgdGhlcmUgaXMgc3RpbGwgY29uc2lkZXJhYmxlIHVuY2VydGFpbnR5IGFib3V0IGZ1dHVyZSB2YWx1ZXMuCi0gCgojIyMjIE1vZGVsIENvbXBhcmlzb24KCmBgYHtyfQojIENvbXBhcmluZyBNb2RlbHMgdXNpbmcgQUlDIGFuZCBCSUMKbW9kZWxzIDwtIGxpc3QoYXJfbW9kZWwsIG1hX21vZGVsLCBhcm1hX21vZGVsMSwgYXJtYV9tb2RlbDIsIGFybWFfbW9kZWwzKQptb2RlbF9uYW1lcyA8LSBjKCJBUiIsICJNQSIsICJBUklNQSgxLDEsMSkiLCAiQVJJTUEoMiwxLDEpIiwgIkFSSU1BKDIsMSwyIiwgIkdBUkNIIikKCmFpY192YWx1ZXMgPC0gYyhzYXBwbHkobW9kZWxzLCBBSUMpLCAtMi4wNzc1KQpiaWNfdmFsdWVzIDwtIGMoc2FwcGx5KG1vZGVscywgQklDKSwgLTEuOTQ3MykKCmNvbXBhcmlzb24gPC0gZGF0YS5mcmFtZShNb2RlbD1tb2RlbF9uYW1lcywgQUlDPWFpY192YWx1ZXMsIEJJQz1iaWNfdmFsdWVzKQpwcmludChjb21wYXJpc29uKQpgYGAKCi0gQmFzZWQgb24gYm90aCBBSUMgYW5kIEJJQyBjcml0ZXJpYSwgdGhlIEdBUkNIIG1vZGVsIGlzIHRoZSBiZXN0LXN1aXRlZCBtb2RlbCBmb3IgeW91ciBkYXRhLgotIEdBUkNIIGlzIG9mdGVuIHByZWZlcnJlZCBmb3IgZmluYW5jaWFsIHRpbWUgc2VyaWVzIGRhdGEgd2hlcmUgdm9sYXRpbGl0eSBjbHVzdGVyaW5nIGlzIHByZXNlbnQsIGFzIGl0IG1vZGVscyBjaGFuZ2luZyB2YXJpYW5jZSBvdmVyIHRpbWUsIHdoaWNoIEFSSU1BIG1vZGVscyBkbyBub3QgaGFuZGxlIHdlbGwuCi0gVGhlIHNpZ25pZmljYW50bHkgbG93ZXIgQUlDIGFuZCBCSUMgdmFsdWVzIGZvciB0aGUgR0FSQ0ggbW9kZWwgc3VnZ2VzdCBpdCBmaXRzIHRoZSBkYXRhIGJldHRlciwgbGlrZWx5IGNhcHR1cmluZyBwYXR0ZXJucyBvZiB2b2xhdGlsaXR5IG1vcmUgZWZmZWN0aXZlbHkgdGhhbiB0aGUgQVIgb3IgQVJJTUEgbW9kZWxzLgoKCgoKCgoKCgoK